sizeof 部分用法

1、指針變量的sizeof
指針記錄了另一個對象的地址。既然是來存放地址的,那麼它當然等於計算機內部地址總線的寬度。所以在32位計算機中,一個指針變量的返回值必定是4(注意結果是以字節爲單位)。
char* pc = "abc";
int* pi;
string* ps;
char** ppc = &pc;
void (*pf)();//指針函數
sizeof( pc ); // 結果爲4
sizeof(pc+3);//結果爲4
sizeof( pi ); // 結果爲4
sizeof( ps ); // 結果爲4
sizeof( ppc ); // 結果爲4
sizeof( pf );// 結果爲4
指針變量的sizeof值與指針所指的對象沒有任何關係,正是由於所有的指針變量所佔內存大小相等,所以MFC消息處理函數使用兩個參數WPARAM、LPARAM就能傳遞各種複雜的消息結構(使用指向結構體的指針)

2、數組的sizeof
數組的sizeof值等於數組所佔用的內存字節數,如:
char a1[] = "abc";
int a2[3];
sizeof( a1 ); // 結果爲4,字符 末尾還存在一個NULL終止符
sizeof( a2 ); // 結果爲3*4=12(依賴於int)

void foo3(char a3[3])
{
int c3 = sizeof( a3 ); // c3 ==
}
void foo4(char a4[])
{
int c4 = sizeof( a4 ); // c4 ==
}
也許當你試圖回答c4的值時已經意識到c3答錯了,是的,c3!=3。這裏函數參數a3已不再是數組類型,而是蛻變爲指針,相當於char* a3,爲什麼仔細想想就不難明白,我們調用函數foo1時,程序會在棧上分配一個大小爲3的數組嗎不會!數組是“傳址”的,調用者只需將實參的地址傳遞過去,所以a3自然爲指針類型(char*),c3的值也就爲4。

3、結構體的sizeof
struct S1
{
char c;
int i;
};
sizeof(S1)=8;
字節對齊細節和編譯器實現相關,但一般而言,滿足三個準則:
1) 結構體變量的首地址能夠被其最寬基本類型成員的大小所整除;
2) 結構體每個成員相對於結構體首地址的偏移量(offset)都是成員大小的整數倍,如有需要編譯器會在成員之間加上填充字節(internal padding);
3) 結構體的總大小爲結構體最寬基本類型成員大小的整數倍,如有需要編譯器會在最末一個成員之後加上填充字節(trailing padding)。
struct S3
{
char c1;
S1 s;
char c2;
};
S1的最寬簡單成員的類型爲int,S3在考慮最寬簡單類型成員時是將S1“打散”看的,所以S3的最寬簡單類型爲int,這樣,通過S3定義的變量,其存儲空間首地址需要被4整除,整個sizeof(S3)的值也應該被4整除。
c1的偏移量爲0,s的偏移量呢這時s是一個整體,它作爲結構體變量也滿足前面三個準則,所以其大小爲8,偏移量爲4,c1與s之間便需要3個填充字節,而c2與s之間就不需要了,所以c2的偏移量爲12,算上c2的大小爲13,13是不能被4整除的,這樣末尾還得補上3個填充字節。最後得到sizeof(S3)的值爲16。
4、聯合體的sizeof
結構體在內存組織上是順序式的,聯合體則是重疊式,各成員共享一段內存,所以整個聯合體的sizeof也就是每個成員sizeof的最大值。結構體的成員也可以是複合類型,這裏,複合類型成員是被作爲整體考慮的。
所以,下面例子中,U的sizeof值等於sizeof(s)。
union U
{
int i;
char c;
S1 s;
};

發佈了29 篇原創文章 · 獲贊 3 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章