1. 程式人生 > >[轉]sizeof計算空間大小的總結

[轉]sizeof計算空間大小的總結

兩個 壓縮 tof int size_t 算數 環境 min char

原文鏈接: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計算空間大小的總結