1,基本變量的大小和對齊值
基本變量的大小就不用說了,char 1 int 4 double 8 等等。
基本變量的對齊值,就是他的大小。
代碼:
int n;
int *p=&n;
cout<<p;
輸出的值一定是4的倍數,因爲int變量的對齊值是4,這樣做是爲了讓數據的處理效率更高,因爲計算機是一次讀取4個字節的。
也就是說,基本變量的地址,是其對齊值的倍數。
2,結構體的大小和對齊值
有3條規則:
1) 結構體變量的首地址能夠被其最寬基本類型成員的大小所整除;
2) 結構體每個成員相對於結構體首地址的偏移量都是成員大小的整數倍,如有需要編譯器會在成員之間加上填充字節;
3) 結構體的總大小爲結構體最寬基本類型成員大小的整數倍,如有需要編譯器會在最末一個成員之後加上填充字節。
也可以這麼理解:
首先,結構體的對齊值是所有成員的最大對齊值。
其次,結構體的第一個成員的地址必須是結構體的對齊值的倍數,按照“基本變量的地址是其對齊值的倍數”這個原則依次確定每個變量的地址。
最後,結構體的大小是結構體的對齊值的倍數。
3,結構體的嵌套
結構體嵌套時,不能按照展開處理,而是把內層的結構體變量當做基本變量,它的大小和對齊值按照上述方法計算。
這個場景讓我們更清楚的認識到,結構體成員地址是它的大小的倍數這句話是錯的,應該是結構體成員地址是它的對齊值的倍數。
4,pragma指定對齊值
如果pragma pack指定了對齊值,那麼基本變量的對齊值,就是他的大小和指定對齊值中較小的數。
確定了基本變量的對齊值之後,還是按照我上面說的規則確定結構體的大小和對齊值。
5,空數組成員
struct n1
{
char c;
int x[0];
};
struct n2
{
int c;
int x[0];
};
struct n3
{
char c;
int x[];
};
struct n4
{
int c;
int x[];
};
4個結構體的大小都是4
struct n1
{
char c;
char x[0];
};
struct n2
{
int c;
char x[0];
};
struct n3
{
char c;
char x[];
};
struct n4
{
int c;
char x[];
};
4個結構體的大小分別是1 4 1 4
也就是說,空數組是一種大小爲0的變量類型,他的對齊值和數組成員的對齊值一樣。