[轉]sizeof計算空間大小的總結
原文鏈接:http://www.cnblogs.com/houjun/p/4907622.html
關於sizeof的總結
1、sizeof的使用形式:sizeof(var_name)或者sizeof var_name
2、變量名可以不用括號括住:sizeof a
3、數據類型必須用括號括起來:sizeof(int)
4、sizeof可以對表達式求值:sizeof(2+3.14),實際是sizeof(double)
5、sizeof可以對函數調用求值,實際上是對返回值類型求值
6、以下情況不能用sizeof進行求值
1)不能對函數名求值
2)不能對不確定返回值的類型求值,如void
3)位域成員不可以使用sizeof求值
7、sizeof的結果是size_t,它被定義為unsigned int類型。該類型保證容納顯示所建立的最大對象的字節大小。
一般,在32位編譯器下:
sizeof(int):4
sizeof(short):2
sizeof(long):4
sizeof(long long):8
sizeof(float):4
sizeof(double):8
sizeof(char):1
sizeof(p):4,(p為指針)
在不同的系統中這些值不一樣。
8、sizeof與strlen()比較,在計算字符數組時,sizeof包含‘\0‘,strlen()不包含‘\0‘
9、32位系統下指針的sizeof是4字節,64位下是8字節
10、對引用的sizeof,其實是對其所綁定的對象的sizeof
11、對於C字符串,需要牢記C/C++中一個漢字占兩個字節(Linux下3個字節),且字符串尾有空字符。
12、對數組sizeof可以計算數組的大小
13、數組作為形參時,數組名的sizeof是4個字節
14、32bit系統中,int **a[3][4];sizeof(a)=48
15、關於struct的空間計算
很多公司喜歡在考察struct的空間計算,是的,我深有感受。
struct的空間計算比較復雜,總體遵循兩個規則:
1)在windows32環境下,整體空間是占用空間最大的成員(的類型)所占字節的整數倍,在Linux+gcc環境下,若最大成員類型所占字節數超過4,如double是8,則整體空 間是4的整數倍即可。
2)在windows32環境下,數據對其原則——內存結構體成員的先後順序排列,當排到該成員變量時,其前面已經擺放的空間大小必須是該成員類型大小的整數倍,如果不夠 則補齊,以此類推。但在Linux+gcc環境下,若成員類型超過4,如double是8,則前面已經擺放的空間大小是4的整數倍即可,不夠則補全。
win32環境下:在擺放時,思路是:
1、首先把第一個成員放在地址為0的地方
2、然後再根據第二個成員的類型大小尋找其擺放的起始位置,擺放起始位置必須是類型大小的整數倍,依次類推。
3、最後,再計算整體空間是不是最大類型大小的整數倍。
而在Linux+gcc環境下:擺放的思路是
1、首先把第一個成員放在地址為0的地方
2、如果一個單元裝不下,則另放在一個單元地址的起始位置。
3、最後,如果最大類型帶下超過4,再計算整體空間是不是4的整數倍。
16、含有結構體的結構體的空間計算:
1)在windows32環境下,整體空間是子結構體與父結構體中,占用空間最大的成員(的類型)所占字節的整數倍,在Linux+gcc環境下,若最大成員類型所占字節數超過4,如 double是8,則整體空間是4的整數倍即可。
2)在windows32環境下,數據對其原則——父結構體內存按照結構體成員的先後順序排列,當排到子結構體成員時,其前面已經擺放的空間大小必須是該子結構體成員中最 大類型大小的整數倍,不夠則補全,一次類推。
win32環境下:在擺放時,思路是:
1、首先把第一個成員放在地址為0的地方
2、然後再根據第二個成員的類型大小尋找其擺放的起始位置,擺放起始位置必須是類型大小的整數倍,如果是子結構體,則尋找擺放的起始位置是子結構體中最大類型大小 的整數倍,依次類推。
3、最後,再計算整體空間是不是父子結構體中最大類型大小的整數倍。
Linux+gcc比較省內存,類型大小超過4,起始位置要是4的整數倍即可。
17、含有數組的結構體的空間計算:
在結構體中,數組是按照單個變量一個一個進行擺放,而不是視為整體,故包含數組的結構體對齊的方式比較特殊。
如:
struct S1
{
char a[8];
int b;
};
sizeof(S1)=12,而不是16。
18、含位域結構體的計算
位域成員不能單獨被去sizeof值,但是含有位域的結構體可以。
使用位域有如下規則:
1)如果相鄰位域字段的類型相同,且其位寬之和小於類型的sizeof大小,則後面的字段將緊鄰前面一個字段的存儲,知道不能容納為止。
在vs2010下,一個int a:4,如果後面不是位域,則占4個字節,即其類型的大小。而在Dec-C++與gcc下,無論是不是位域,所占字節數以其實際占用字節數為準,即int a:4,如果後面不是位域,僅占一個字節。
2)如果相鄰位域字段的類型相同,但其位寬之和大於類型的sizeof大小,則後面的字段將從新的存儲單元開始,其偏移量為其類型大小的整數倍。
3)如果相鄰位域字段的類型不同,不同編譯器的具體實現有差異,VC6不采取壓縮,而Dec-C++與gcc采用壓縮。
4)如果位域字段之間穿插著非位域字段,則不進行壓縮。
5)整體結構體的總大小為最快基本類型成員大小的整數倍。
19、使用"#pragma pack"時結構體空間計算
一般可以通過下面的方法來改變默認條件的對其條件:
使用偽指令#pragma pack(n),編譯器將按照n個字節對齊;
使用偽指令#pragma pack(n),將取消自定字節對齊方式。
以上兩種指令通常應該搭配使用。
#pragma pack(n),n為字節對齊數,其取值為1、2、4、8、16等,默認是8,如果這個值比結構體的sizeof值小,那該成員的偏移量應該以此為準,即結構體成員的偏移量應 該取二者的最小值。公式如下:
offsetof(item)=min(n,sizeof(item))
20、union的空間計算
聯合體的sizeof值是所有成員sizeof的最大值。
21、枚舉的空間計算
enum只是定義了一個常量集合,裏面沒有“元素”,而枚舉是當做int類型存儲的,故枚舉類型的sizeof值為4。
[轉]sizeof計算空間大小的總結