偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

哦!數(shù)組還能這么用,學(xué)到了!

開(kāi)發(fā) 后端
即結(jié)構(gòu)體的最后一個(gè)成員,可以不完整類型(一種缺乏足夠的信息去描述一個(gè)完整對(duì)象的類型)的數(shù)組,但它使得整個(gè)結(jié)構(gòu)體的大小就像沒(méi)有這個(gè)成員一樣。

這個(gè)問(wèn)題源于讀者在閱讀redis源碼時(shí)的一個(gè)疑問(wèn)。

先看下面的代碼,對(duì)于包含動(dòng)態(tài)字符串成員的兩個(gè)結(jié)構(gòu)體Test0和Test1占用空間分別是多少呢? 

  1. //來(lái)源:公眾號(hào)【編程珠璣】  
  2. //作者:守望先生  
  3. #include<stdio.h>  
  4. struct Test0  
  5.  
  6.     int a;  
  7.     int b;  
  8.     char *c;  
  9. };  
  10. struct Test1  
  11.  
  12.     int a;  
  13.     int b;  
  14.     char c[];  
  15. };  
  16. int main(void)  
  17.  
  18.     printf("sizeof(struct Test0) = %zd\n",sizeof(struct Test0));  
  19.     printf("sizeof(struct Test1) = %zd\n",sizeof(struct Test1));  
  20.     return 0;  

很多讀者一眼就能看出來(lái),在64位系統(tǒng)上,編譯為64位程序,其輸出結(jié)果為: 

  1. 16  

對(duì)于Test0的結(jié)果是16,通常沒(méi)有什么疑問(wèn),畢竟4(int)+4(int)+8(指針)= 16,但是對(duì)于后者的結(jié)構(gòu)體占用空間為8字節(jié),有的讀者可能會(huì)有疑問(wèn)。(關(guān)于字節(jié)對(duì)齊,參考《字節(jié)對(duì)齊,看這篇就懂了》)

柔性數(shù)組(flexible array)

實(shí)際上這是在C99中引入的柔性數(shù)組的特性。即結(jié)構(gòu)體的最后一個(gè)成員,可以不完整類型(一種缺乏足夠的信息去描述一個(gè)完整對(duì)象的類型)的數(shù)組,但它使得整個(gè)結(jié)構(gòu)體的大小就像沒(méi)有這個(gè)成員一樣。但是呢,當(dāng)用結(jié)構(gòu)體通過(guò)這個(gè)名字訪問(wèn)這個(gè)成員時(shí),就像訪問(wèn)一個(gè)普通數(shù)組成員一樣。

如果數(shù)組最終一個(gè)元素都沒(méi)有的話,那么訪問(wèn)這個(gè)數(shù)組將會(huì)是未定義行為了。

正如我們前面所看到的: 

  1. struct Test1  
  2.  
  3.     int a;  
  4.     int b;  
  5.     char c[];  
  6. }; 

成員c是一個(gè)數(shù)組,但是并沒(méi)有指定大小,使用sizeof計(jì)算Test1,其占用空間也僅僅是8字節(jié)。

有什么好處?

那么使用柔性數(shù)組有什么好處呢?

內(nèi)存申請(qǐng)和釋放

假設(shè)分別使用兩種類型的結(jié)構(gòu)體,存儲(chǔ)16字節(jié)的字符數(shù)據(jù),需要申請(qǐng)內(nèi)存。對(duì)于struct Test0: 

  1. strcut Test0 *t0 = malloc(sizeof(struct Test0));//為結(jié)構(gòu)體申請(qǐng)內(nèi)存  
  2. t0->c = malloc(sizeof(char) * 16);//為成員指向的數(shù)據(jù)申請(qǐng)內(nèi)存 

而對(duì)于struct Test1: 

  1. strcut Test1 *t1 = malloc(sizeof(struct Test1) + sizeof(char) * 16); 

看出區(qū)別了嗎?前者需要兩次內(nèi)存申請(qǐng),而后者只需要一次。前者地址不連續(xù)(兩次malloc),后者地址連續(xù)。而你訪問(wèn)成員c的時(shí)候,只需要下面這樣就可以:

t1->c,和普通成員無(wú)異。

要判斷它們的地址是否連續(xù)也非常簡(jiǎn)單,只需要分別打印b和c的地址就可以了。

和內(nèi)存釋放類似,前面需要單獨(dú)釋放成員c申請(qǐng)的內(nèi)存,而后者可以一起釋放。

數(shù)據(jù)拷貝

正由于前面的差別,導(dǎo)致數(shù)據(jù)拷貝時(shí),更有區(qū)別。

對(duì)于struct Test0: 

  1. //memcpy(t0copy,t0,sizeof(struct Test0));//不可,這樣直接t0copy的c和t0的c指向同一片內(nèi)存區(qū)域。  
  2. t0t0copy.a = t0.a;  
  3. t0t0copy.b = t0.b;  
  4. memcpy(t0copy.c,t0.c,sizeof(char)*16); 

這里無(wú)法一次拷貝,因?yàn)樗某蓡Tc是一個(gè)指針類型,我們需要的是一份完整拷貝,因此必須拷貝它指向的內(nèi)存。(參考《結(jié)構(gòu)體成員賦值到底是深拷貝還是淺拷貝?》)

但是對(duì)于struct Test1: 

  1. memcpy(t0copy,t0,sizeof(strcut Test1) + sizeof(char) * 16); 

在這里,由于柔性數(shù)組的內(nèi)存,它的數(shù)據(jù)內(nèi)容和結(jié)構(gòu)體數(shù)據(jù)成員的地址是連續(xù)的,因此可以直接拷貝。

減少內(nèi)存碎片

由于結(jié)構(gòu)體的柔性數(shù)組和結(jié)構(gòu)體成員的地址是連續(xù)的,即可一同申請(qǐng)內(nèi)存,因此更大程度地避免了內(nèi)存碎片。另外由于該成員本身不占結(jié)構(gòu)體空間,因此,整體而言,比普通的數(shù)組成員占用空間要會(huì)稍微小點(diǎn)。

零長(zhǎng)數(shù)組

與柔性數(shù)組功能類似,還有一個(gè)0長(zhǎng)數(shù)組,不過(guò)它并不是標(biāo)準(zhǔn)中的,但是它可以實(shí)現(xiàn)類似的功能,使用方式如下: 

  1. struct Test1  
  2.  
  3.     int a;  
  4.     int b;  
  5.     char c[0];  
  6. }; 

差別在于使得數(shù)組長(zhǎng)度為0。但是由于它并非C標(biāo)準(zhǔn)中的,因此從可移植性考慮,不建議使用這種方式,除非你還無(wú)法使用C99。

總結(jié)

柔性數(shù)組的使用:

  •  位于結(jié)構(gòu)體最后一個(gè)位置
  •  不完整數(shù)組類型
  •  不是唯一成員

最后,放張圖,看差別:

普通和柔性數(shù)組

 

 

責(zé)任編輯:龐桂玉 來(lái)源: C語(yǔ)言與C++編程
相關(guān)推薦

2017-03-17 13:40:48

思科視頻

2021-08-29 18:13:03

緩存失效數(shù)據(jù)

2021-11-22 11:05:20

Vue 3setup前端

2022-10-28 19:19:11

ChromeNetwork網(wǎng)絡(luò)

2020-07-21 18:54:21

Rust類型轉(zhuǎn)換語(yǔ)言

2019-03-28 11:07:56

Spring BootRedis緩存

2023-10-16 08:55:43

Redisson分布式

2022-02-14 21:58:58

netstatLinuxWindows

2013-03-26 13:26:41

婚禮微信微信公眾賬號(hào)

2021-03-09 09:55:02

Vuejs前端代碼

2023-04-10 07:40:36

GraphQLRest通信模式

2022-10-31 08:47:21

人臉識(shí)別按鍵鍵盤

2024-11-13 09:22:40

2022-07-19 08:04:04

HTTP應(yīng)用層協(xié)議

2023-06-03 00:05:18

TypeScriptJSDoc掃描器

2020-05-09 16:45:56

ping命令Linux

2024-04-12 08:54:13

從庫(kù)數(shù)據(jù)庫(kù)應(yīng)用

2021-09-03 06:46:34

MyBatis緩存后端

2010-01-20 10:37:48

Chrome瀏覽器

2019-12-30 09:51:35

Word設(shè)計(jì)模式軟件
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)