性无码一区二区三区在线观看,少妇被爽到高潮在线观看,午夜精品一区二区三区,无码中文字幕人妻在线一区二区三区,无码精品国产一区二区三区免费

由sizeof 這個(gè)“管”,窺一窺C語(yǔ)言這只“豹”

在C語(yǔ)言開發(fā)中,sizeof()是一個(gè)什么樣的存在呢?有多少人認(rèn)為它是個(gè)函數(shù)?或者曾經(jīng)是否也認(rèn)為它是函數(shù)呢?

今天我們介紹下sizeof()的同時(shí),并通過它延伸展開,來聊一聊一些C語(yǔ)言的基礎(chǔ)知識(shí)。

1、sizeof是什么?

sizeof是C語(yǔ)言中的關(guān)鍵字,也可以認(rèn)為是一種運(yùn)算符。 是一個(gè)判斷數(shù)據(jù)類型或者表達(dá)式長(zhǎng)度的運(yùn)算符。

2、sizeof的使用及C語(yǔ)言知識(shí)延伸

通過實(shí)際的代碼編寫并使用printf();函數(shù)來輸出要展示的結(jié)果,來向大家詳細(xì)進(jìn)行說明。(編輯編譯環(huán)境 :C FREE-5)

1)測(cè)試基本數(shù)據(jù)類型的長(zhǎng)度

#include #define uint8_t unsigned char #define uint32_t unsigned intint main(void){ //基本數(shù)據(jù)類型 printf("uint8_t length = %d\r\n",sizeof(uint8_t));printf("\r\n");printf("uint32_t length = %d\r\n",sizeof(uint32_t));}

通過編譯輸出如下內(nèi)容:

可以看出uint8_t 類型占用1個(gè)字節(jié) 。uint32_t 類型占用4個(gè)字節(jié)。沒毛病,咱們繼續(xù)。

2)測(cè)試普通變量的數(shù)據(jù)長(zhǎng)度

#include #define uint8_t unsigned char #define uint32_t unsigned intuint32_t Var ;//普通變量 int main(void){  //普通變量 printf("Var length = %d\r\n",sizeof(Var));printf("\r\n");}

通過編譯輸出如下內(nèi)容:

我在代碼中定義了一個(gè)uint32_t 類型的變量,毫無懸念,這個(gè)變量也占4個(gè)字節(jié)。繼續(xù)往下看:

3)測(cè)試數(shù)組的數(shù)據(jù)長(zhǎng)度

#include #define uint8_t unsigned char #define uint32_t unsigned intuint32_t Array_A[10];//普通數(shù)組 int main(void){ //普通數(shù)組 printf("Array_A length = %d\r\n",sizeof(Array_A));printf("\r\n");printf("Array_A[10] length = %d\r\n",sizeof(Array_A[10])); printf("\r\n");printf("&Array_A length = %d\r\n",sizeof(&Array_A));printf("\r\n");printf("&Array_A[0] length = %d\r\n",sizeof(&Array_A[0]));printf("\r\n");}

通過編譯輸出如下內(nèi)容:

這里我重點(diǎn)說下,通過測(cè)試我們可以看到:

sizeof()的括號(hào)中,直接寫數(shù)組的名字,則求的是整個(gè)數(shù)組所占用的字節(jié)數(shù)。

sizeof()的括號(hào)中,寫入Array_A[10],居然也可以等于4,因?yàn)锳rray_A[10]這個(gè)數(shù)組定義的是uint32類型的,從Array_A[0]到Array_A[9],所以任何一個(gè)元素都是4字節(jié),但是Array_A[10]這個(gè)元素下標(biāo)到10了,明顯溢出。軟件居然沒有報(bào)錯(cuò),甚至都沒有警告。這個(gè)地方要注意一下。

sizeof()的括號(hào)中,寫入&Array_A,代表數(shù)組首地址,占用4個(gè)字節(jié)。

sizeof()的括號(hào)中,寫入&Array_A[0],代表數(shù)組首元素地址,也占用占用4個(gè)字節(jié)。

4)測(cè)試指針變量的數(shù)據(jù)長(zhǎng)度

#include #define uint8_t unsigned char #define uint32_t unsigned intuint32_t Var ;//普通變量 uint32_t *p = &Var;//指針 int main(void){ //指針 printf("p length = %d\r\n",sizeof(&p));printf("\r\n");printf("*p length = %d\r\n",sizeof(*p));printf(" \r\n");}

通過編譯輸出如下內(nèi)容:

為什么&p的長(zhǎng)度和*p的長(zhǎng)度都是4個(gè)字節(jié)呢?

“printf("p length = %d\r\n",sizeof(&p));”這一條輸出指針地址的長(zhǎng)度。是4個(gè)字節(jié)。

“printf("*p length = %d\r\n",sizeof(*p));”這一條輸出的是指針?biāo)赶蜃兞款愋偷拈L(zhǎng)度。也就是這句話:“uint32 *p = &Var" 從上面我們可以得知Var的數(shù)據(jù)類型就是uint32_t,也是4個(gè)字節(jié)。

好,下面我們來稍微做個(gè)更改:

#include #define uint8_t unsigned char #define uint32_t unsigned intuint8_t Var ;//普通變量 uint8_t *p = &Var;//指針 int main(void){ //指針 printf("p length = %d\r\n",sizeof(&p));printf("\r\n");printf("*p length = %d\r\n",sizeof(*p));printf("\r\n");}

這這里我把 Var的數(shù)據(jù)類型由uint32_t 改為uint8_t ,把uint32_t *p 改為 uint8_t *p。然后大家可以思考一下:

 “printf("p length = %d\r\n",sizeof(&p)); “輸出多少?

“printf("*p length = %d\r\n",sizeof(*p));”輸出多少?

下面我們來看結(jié)果:

由編譯結(jié)果可以看到,&p的長(zhǎng)度是4。是4個(gè)字節(jié)嗎?和你想得一樣嗎?這個(gè)結(jié)果對(duì)嗎?我們不是把uint32_t *p 改為 uint8_t *p了嗎?不應(yīng)該是1個(gè)字節(jié)嗎?

這里引伸出一個(gè)重要的結(jié)論: *號(hào)前面的數(shù)據(jù)類型只是表示指針?biāo)赶虻膬?nèi)存里數(shù)據(jù)的類型,并不代表指針地址的類型。它和指針的大小無關(guān),并不會(huì)對(duì)指針的長(zhǎng)度產(chǎn)生影響。指針的地址大小是和所處的編譯環(huán)境有關(guān)系。 

*p的長(zhǎng)度,這里編譯結(jié)構(gòu)現(xiàn)實(shí)變成了1個(gè)字節(jié)。因?yàn)橹羔樦赶虻臄?shù)據(jù)類型改成了uint8_t ,也就是Var變量變成了1.因?yàn)閂ar 的數(shù)據(jù)類型是 uint8_t ,所以對(duì)應(yīng)的*p前面的數(shù)據(jù)類型也要是uint8_t,  這樣才能保持一致,否則編譯器會(huì)提示不兼容。這也從側(cè)面應(yīng)證了: *號(hào)前面的數(shù)據(jù)類型只是表示指針?biāo)赶虻膬?nèi)存里數(shù)據(jù)的類型,并不代表指針地址的類型。”  

這個(gè)內(nèi)容就說到這里,感興趣的朋友可以在自己的編譯環(huán)境上測(cè)試一下。

5)測(cè)試構(gòu)造數(shù)據(jù)類型的數(shù)據(jù)長(zhǎng)度

#include #define uint8_t unsigned char #define uint32_t unsigned inttypedef struct{uint8_t Var1;uint8_t Var2;uint32_t Var3;}ST_Test; typedef union{ ST_Test st_test;uint8_t Array_B[10];}UN_Test;int main(void){ //構(gòu)造數(shù)據(jù)類型 printf("ST_Test length = %d\r\n",sizeof(ST_Test));printf("\r\n");printf("UN_Test length= %d\r\n",sizeof(UN_Test));printf("\r\n");}

通過編譯輸出如下內(nèi)容:

我們接著來看,首先第一個(gè)構(gòu)造的數(shù)據(jù)類型是一個(gè)結(jié)構(gòu)體:根據(jù)編譯輸出的提示,該結(jié)構(gòu)體占用的長(zhǎng)度為8個(gè)字節(jié)。為什么是8個(gè)字節(jié),不是6個(gè)字節(jié)?在結(jié)構(gòu)體中,數(shù)據(jù)長(zhǎng)度不是單純的相加,而是會(huì)涉及到字節(jié)對(duì)齊的問題。網(wǎng)上有很多這方面的資料,這里不深入展開了。

第二個(gè)構(gòu)造的數(shù)據(jù)類型是共用體。共用體和結(jié)構(gòu)體的最大區(qū)別就是內(nèi)部的各個(gè)成員變量共用一塊內(nèi)存。內(nèi)存大小取決于成員變量中最大的成員。那按道理這個(gè)共用體的長(zhǎng)度應(yīng)該是10呀。因?yàn)楣灿皿w內(nèi)的兩個(gè)成員,結(jié)構(gòu)體成員是8個(gè)字節(jié),Array_B[10]是10個(gè)字節(jié)。為什么是12呢?同理,也是字節(jié)對(duì)齊的原因。

然后接著再做一個(gè)延伸:

#include #define uint8_t unsigned char #define uint32_t unsigned inttypedef struct{uint8_t Var1;uint8_t Var2;uint32_t Var3;}ST_Test;#pragma pack(1)typedef union{ ST_Test st_test;uint8_t Array_B[10];}UN_Test;#pragma pack()int main(void){ //構(gòu)造數(shù)據(jù)類型 printf("ST_Test length = %d\r\n",sizeof(ST_Test));printf("\r\n");printf("UN_Test length= %d\r\n",sizeof(UN_Test));printf("\r\n");}

編譯輸出為:

通過使共用體一字節(jié)對(duì)齊后,可以看到它的數(shù)據(jù)類型占用的內(nèi)存大小就變成了10個(gè)字節(jié)。

共用體可以用來測(cè)試數(shù)據(jù)存儲(chǔ)模式是大端模式還是小端模式。限于篇幅,這里就不展開了。感興趣的朋友自行百度。

這就是今天要分享的內(nèi)容,比較基礎(chǔ)。給不清楚這塊知識(shí)的朋友提供個(gè)思路。明白了這塊的朋友也可以借此機(jī)會(huì)復(fù)習(xí)一下。說得不對(duì)的地方,還請(qǐng)各位朋友提出寶貴意見。一起學(xué)習(xí),共同進(jìn)步一直是本號(hào)的宗旨之一。 

聲明:本內(nèi)容為作者獨(dú)立觀點(diǎn),不代表電子星球立場(chǎng)。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請(qǐng)聯(lián)系:editor@netbroad.com
覺得內(nèi)容不錯(cuò)的朋友,別忘了一鍵三連哦!
贊 1
收藏 2
關(guān)注 30
成為作者 賺取收益
全部留言
0/200
成為第一個(gè)和作者交流的人吧