结构体对齐计算方式
目錄
- 法則一:結構體成員的偏移量必須是成員大小的整數倍(數組除外)
- 法則二:結構體大小必須是所有成員大小的整數倍(數組、結構體除外)
- 帶數組的結構體大小計算
- 帶結構體的結構體大小計算
- 帶聯合體的結構體大小計算
- pragma pack(4)向4對齊
對齊方式確實很浪費空間,可是按照計算機的訪問規則,這種對齊方式提升了效率。
法則一:結構體成員的偏移量必須是成員大小的整數倍(數組除外)
#include<stdio.h> #include<stdlib.h>struct s1{char ch1; //1char ch2; //1int i; //4 2 };int main() {printf("char = %d\n",sizeof(char));printf("float = %d\n",sizeof(float));printf("int = %d\n",sizeof(int));printf("double = %d\n",sizeof(double));printf("S1 = %d\n",sizeof(struct s1));return 0;}首先,第一個成員ch1 的偏移量為0(可以這么理解 距離結構體頭距離為0),ch1的類型為char,大小為1字節,0被認為是任何數的整數倍,所以到ch1這里大小為1;
第二個成員ch2,ch2的偏移量是前面成員的大小和(這個大小和是遵循第一法則的前提下的大小和,不是隨意加起來就行的),所以ch2的偏移量為1,1滿足ch2的大小1的整數倍,所以到ch2這里大小為1+1 = 2;
最后i,int i的偏移量為1+1 = 2,但2不是int型大小4的整數倍,所以要在前面加上2(多偏移兩個),將之變為4,才滿足第一法則。
綜上s1的大小為1+1+2+4 = 8;
法則二:結構體大小必須是所有成員大小的整數倍(數組、結構體除外)
struct s2{char ch1; //1int i; //4 3char ch2; //1 3};根據第一法則可以簡單計算下s2的大小:
到ch1這里為1
到int這里為1+3+4 = 8
到ch2這里 8+1 = 9;
但是運行結果為12。
因為9不是4和1的整數倍(遵循第二法則),所以要繼續偏移,直到12。
帶數組的結構體大小計算
struct s3{char ch1;int i;char str[10]; };1+3+4+10 = 18,因為18不是4的倍數,所以要偏移到20。這里偏移到20不是因為str數組的大小為10才偏移的,是因為i的大小為4,法則一和法則二都是除數組外。
當結構體里有數組的時候,數組那一成員不遵循偏移量和數組成員大小對齊法則,直接將前面的大小加上數組的大小。 舉個例子:
struct demo{char ch1;int i;char str[32]; };這個demo計算到int i的時候為8,8直接加上數組大小32為40,40正好是4的整數倍,所以demo的大小就為40。
再舉個例子:
struct demo{char ch1;int i;char str[55]; };8+55 = 63,63不是4的整數倍,所以要偏移到64,即demo的大小為64。
帶結構體的結構體大小計算
struct s4{char ch; //1int i; //4 3struct s{ //只是定義了個結構體 不算入char ch1; //int j; //}; float f; //4 };大小:12
struct s4{char ch; //1int i; //4 3struct s{ //定義 并且占用內存8char ch1; //1int j; //4 3}stmp; float f; //4 };
里面這個結構體的大小是8,那么是否結構體大小就要向8對齊呢?這個結構體的大小是20,很明顯不是8的倍數。所以計算結構體大小時是把里面這個結構體就看做是一個char,和一個int,不是看做一個整體。
struct s4{char ch; //1int i; //4 3struct s{ //定義 并且占用內存char ch1; //1int j; //4 3double d; //8}stmp; float f; //4 };
28(不是double的倍數+4)–>32
帶聯合體的結構體大小計算
struct s5{char ch; int i; union{char ch1;int j;}; };結果為12,算結構體大小的時候,如果里面有聯合體,取聯合體里面最大的成員計算。
pragma pack(4)向4對齊
#pragma pack(4) //指定向4對齊 struct s6{char ch;int i;float f;double d; };#pragma pack(4) 這句話是指定計算大小的時候向4對齊
結果為20,不加這句話結果就是24。
1+3+4+4+4+8 = 24。
這一個在ubuntu中運行結果為24,沒有對齊10,是因為最大時double,如果指定的比成員最大的還要大就按照成員最大的對齊。
總結
- 上一篇: 电脑里面英文系统的中文简介
- 下一篇: 扫雷游戏代码html,分享一个用h5制作