原則1:數據成員對齊規則:結構(struct)(或聯合(union))的數據成員,第一個數據成員放在offset爲0的地方,之後每一個數據成員的對齊按照#pragma pack指定的數值和這個數據成員自身長度中,比較小的那個進行。(即pack指定的值和成員自身比較,小的那個整數倍對齊)markdown
原則2:結構(或聯合)的總體對齊規則:在數據成員完成各自對齊以後,結構(或聯合)自己也要進行對齊,對齊將按照#pragma pack指定的數值和結構(或聯合)最大數據成員長度中,比較小的那個進行。(即pack指定的值和最大成員自身比較,小的那個整數倍對齊)網絡
原則3:結構體做爲成員:若是一個結構裏有某些結構體成員,則結構體成員要從其內部最大元素大小的整數倍地址開始存儲。數據結構
#pragma pack(2)
struct Struct1{
double a; //0-7
char b; //8
int c; //起始min(2,4)=2,因此從2的倍數開始 10 11 12 13
short d; //14 15
} structOne; //min(2,8)=2, 2的倍數 16
#pragma pack()
struct Struct2{
double a; //0-7
char b; //8
int c; //起始min(8,4)=4,因此從4的倍數開始 12 13 14 15
short d; //16 17
} structTwo; //min(8,8)=8, 8的倍數 24
複製代碼
運行結果:大數據
能夠看出此時structOne和structTwo,內部成員變量順序徹底一致,指定了#pragma pack()以後sizeof獲得的結果徹底不一樣。spa
#pragma pack(show)
struct Struct1{
double a; //0-7
char b; //8
int c; //起始min(8,4)=4,因此從4的倍數開始 12 13 14 15
short d; //16 17
} structOne; //min(8,8)=8, 8的倍數 24;
struct Struct2{
double a; //0-7
int c; //起始min(8,4)=4,因此從4的倍數開始 8 9 10 11
char b; //12
short d; //14 15
} structTwo; //min(8,8)=8, 8的倍數 16
複製代碼
運行結果code
能夠看出結構體成員順序不一樣,雖然pragma pack相同,sizeof獲得的字節數不一樣。orm
這是由於結構體總體對齊,是按照最大成員變量int長度的和pack默認的8中最小比較是4,4的最小倍數是20;內存
結構體的對齊顯示成員對齊,而後是結構體的總體對齊,根據內存對齊原則,來對齊內存。編譯器
1:根據數據成員對齊:it
根據#pragma pack(x) 根據x這個數值和依次排列的數據成員自身的長度的數作比較,那個小用哪一個。
這樣就排出來了每個數據所佔的地址及位置。是依次排列,可是不是依次挨着排列,要排列的數據要看本身數據成員自身長度的數和x哪一個更小,假設自身數據長度爲4,x爲8,則再看本身要依次排列的地址是否是4的倍數,若是不是,則自動延長地址到4的倍數處,再賦值。
2:數據結構對齊:
當上面那個對齊了每個數據成員後, 如今須要對數據結構總體長度對齊。找出數據結構成員中最大長度的數據的值z,跟x作對比,找到最小的那個,假設x爲8,z爲4,則總體數據結構長度應該是4的整數倍,不夠自動補齊。
3:結構體做爲成員
若是成員內有結構體,須要看結構體中最大的成員的長度h來作比較,是h的倍數。