C++中數據對齊問題。struct、union、enum,類繼承。再談sizeof()


      首先是struct,在C++中,結構體其實和class有很大的相似了。但是有一點不同的是,struct默認是public,而class中是private.

      當然,struct繼承等用法也是可以的。

      共用體的聲明方式是:

     枚舉的聲明方式與共用體比較相似

其中a初始化為0,后面默認增1,若已經初始化,則后面再增1,比如d=6在這里。

struct長度計算

大家猜一下,s1 x;int b=sizeof(x);

他的結果會是多少呢?有人會覺得應該是1+8+4+1=14.

實際上是24.為什么會是這樣呢?這個和結構體的對齊方式有很大關系。總之有兩條

1、整體空間是最大成員占用字節的整數倍,比如這里最大字節占用的是double,他為8,那肯定是8,16,24...

2、內存按照結構體中的數據成員先后排序,並且當前地址應該是以當前成員所占用空間的整數倍。比如在這里double b占用的是8個字節,那么以擺字節就應該是8,16,24.而char a,只有一個字節,則前面空間自動補齊。

按照上面兩點的規則,我們不難得出8+8+4+1,但是應該是8的整數倍,所以是24.

 

 這里有必要補充一下:在Linux+gcc環境下,若最大成員是4,則整體空間只需是4的倍數即可。所以這里只需要是4的倍數,4,8,12,16,20,24..
第二點,在Linux+gcc環境下,若某成員類型所占字節數超過4,那前面已擺放空間只需要是4的倍數即可。這里double b;前面只需補齊4個即可,而不需補齊8個。
故會出現整體空間是20的情況。4+8+4+1=17.但是應該是4的倍數,則為20.

 

     那么聯合體應該是怎么樣的呢?

     很顯然聯合體取值的時候只能取其中的一個,那么,聯合體就是多個成員公用一個內存空間。大家很自然的就想到了,最大那個成員所占用的空間就是聯合體的空間了。

 

    講到了數據的對齊方式,那我們就非常有必要講一下兩種不同機器的存儲方式:大端存儲模式和小端存儲模式。

      大端存儲模式:高位字節存儲低地位內存中,低位字節存儲高位。這里均以0x12345678為例。

   

 

小端存儲模式:低位存儲在高位內存中

在小端系統中,b的ASCII為多少?

 1 union enumName {  2     int i;  3     unsigned char ch[2];  4 };  5 int _tmain(int argc, _TCHAR* argv[])  6 {  7  enumName student;  8        student.i=0x1420;  9     char b=student.ch[0]; 10 }

答案應該是32

小端是低位放低位,高位放高位。則是20   14這樣排放。ch[0]等於0x20.

其實我們平常使用的計算機很多都是小端存儲。

 Update

    本來以為數據對齊的問題已經講完,但是今天看到了一道筆試題,覺得非常有必要再說一下關於類中,繼承類的數據成員對齊問題。

1  class A{ 2  public: 3      int a; 4      char b; 5  }; 6  class B:public A{ 7  public: 8      char c; 9  };

    我們想一下,sizeof(B)是多少呢?肯定有人覺得他應該是9或者1.

     但是其實答案是12.

     為什么是12呢?這里我們就要注意到類的對齊方式了。

     顯然B繼承自A,那么B應該包括了A的數據成員,那么對於A來說大小應該是8,這個和結構體的計算方式是一致的。

     特別注意第二點,子類的對齊還要考慮父類的情況,在這里表現的就是,A中最大為4,那么最后的數據大小應該是4的整數倍,4,8,12,。

     這里本來應該是8+1.但需要自動補齊,因此是12.

 

 轉載請注明出處:http://www.cnblogs.com/xiaoyi115/p/3622135.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM