結構體,公用體,枚舉類型的sizeof
1)枚舉類enum型空間計算
enum只是定義了一個常量集合,里面沒有“元素”,而枚舉類型是當做int來存儲的,所以枚舉類型的sizeof值都為4
1 enum color(red,pink,white,black)c; 2 void main() 3 { 4 cout<<sizeof(enum); //值為4 5 }
2)公用體union空間計算
公用體中的成員公用同一段內存,所以整個聯合體的sizeof是所有成員中占用內存最大的成員的sizeof,聯合體要考慮內存對齊,具體規則下面會講
1 union st{ 2 char a[9]; 3 int b[2]; 4 }s; 5 void mian() 6 { 7 cout<<sizeof(s); //值為12 8 }
結果分析:sizeof(a)=9*1=9,sizeof(b)=2*4=8,選兩者中最大的一個,即9,考慮內存對齊,整體空間長度要是公用體中長度最大的數據類型的整數倍,在這里是int占用空間的整數倍,比9大的且是4的整數倍的最小數是12
3)結構體struct空間計算
- 首先空結構體的長度為1,之所以不是0,因為如果空結構體不占內存,則該結構的的變量將無法存取,且兩個不同的空結構體無法區分
- 非空結構體的計算遵循以下兩個原則:
1.整體空間是結構體中占用空間最大的類型所占字節數的整數倍。特殊:在32位Linux+gcc環境下,若最大的類型所占字節數超過4,如double是8,則整體空間大小是4的整數倍即可
2.數據對齊原則-內存按結構體成員的先后順序排列,當排到該成員變量時,其前面所有成員已經占用的空間大小必須是該成員類型大小的整數倍,如果不夠,則前面的成員占用的空間要補齊,使之成為當前成員類型的整數倍。特殊:在Linux+gcc環境下,若當前成員類型字節數超過4,則前面所有成員已經占用的空間大小是4的整數倍即可,不夠則補齊
范例:
- 結構體成員為普通數據類型成員:
1 struct s{ 2 char a; 3 double b; 4 int c; 5 char d; 6 }; 7 void main() 8 { 9 cout<<sizeof(s); //值為24 10 }
結果分析:首先s中最大的類型為double,長度為8;順序存放s中的成員,sizeof(a)=1,占用一個字節,下一個成員b是double類型,占用8個字節,根據原則2,a占用的內存補齊8的整數倍,即補齊到8個字節,b從第9個字節開始存放,此時共占用16個字節,下一個成員c是int類型,占用4個字節,16是4的整數倍,不用補齊,順序存放c,此時占用空間來到20,d占用一個字節,20+1=21,根據原則1,整體空間大小需是double類型長度的整數倍,需將21補齊到24個字節
- 結構體成員中存在其他結構體類型成員:
規則同上面基本相同,但計算時,設計到的倍數對齊,以子結構體中的最大成員類型占用的空間為基礎,而不是將子結構體的整體空間為基礎,具體如下:
1.整體空間是子結構體與父結構體中占用空間最大的類型所占字節數的整數倍。特殊:在32位Linux+gcc環境下,若最大的類型所占字節數超過4,如double是8,則整體空間大小是4的整數倍即可
2.數據對齊原則-內存按結構體成員的先后順序排列,當排到子結構體成員時,其前面所有成員已經占用的空間大小必須是該子結構體成員中占用空間最大的類型大小的整數倍,如果不夠,則前面的成員占用的空間要補齊,使之成為該類型大小的整數倍。特殊:在Linux+gcc環境下,若當前成員類型字節數超過4,則前面所有成員已經占用的孔家大小是4的整數倍即可,不夠則補齊
1 struct s1{ 2 char c; 3 int i; 4 }; 5 6 struct s2{ 7 char c1; 8 s1 s; 9 char c2; 10 }; 11 12 void mian() 13 { 14 cout<<sizeof(s1)<<endl; //8 15 cout<<sizeof(s2)<<endl; //16 16 }
結果分析:
s1:c占一個字節,i占4個字節,存放i之前將其補齊到4個字節,i從第5個字節開始存放,此時整體空間大小是8,恰好是4的整數倍
s2:c1占一個字節,下一個成員s,這里sizeof(s)雖然等於8,但計算時前面占用空間只要是s中最大類型的空間長度的整數倍即可,s中最大類型是int,所以c1占用的內存補齊到4,然后存放s(注意這里存放的是s,而不是int占用的字節),已計算出sizeof(s)=8,此時整體空間來到12,c2占一個字節,12+1=13,根據原則1,整體空間大小需是父結構體和子結構體重最大類型長度int的整數倍,最近的是16.