環境:html
win7_x64旗艦版、VS2015企業版數據結構
說明:爲了提升 CPU 的存儲速度,編譯器會對 struct 和 union的存儲進行優化,即進行字節對齊。優化
1. 指定對齊參數值:經過#pragma pack(push, n)設置。spa
2. 自身對齊參數值:每一個內部類型自身也都有一個對齊參數,通常來講這個對齊參數就是 sizeof(type) 的值,也就是char的自身對齊參數是1,short是2,int是4,float也是4,double是8等。code
3. 有效對齊參數值:內部類型的有效對齊是指它的自身對齊參數和指定對齊參數中較小的那個值;htm
4. 結構體總體的有效對齊參數值:是指它的成員中,有效對齊參數最大的那個值。blog
例如:內存
///< 假設按4字節對齊
#pragma pack(push, 4) struct data { char a; //a的有效對齊參數值是min(1,4)爲1字節,從第1字節開始,佔1字節 char b; //b的有效對齊參數值是min(1,4)爲1字節,從第2字節開始,佔1字節 long long c; //d的有效對齊參數值是min(8,4)爲4字節,從第5個字節開始,佔8字節 short d; //e的有效對齊參數值是min(2,4)爲2字節,從第13個字節開始,佔2字節 };
它們的和爲1字節(a)+1字節(b)+2字節(填充)+8字節(c)+2字節(d)=14字節。資源
由於總體結構體還須要進行對齊,結構成員最大有效對齊參數值爲4,因此整個結構爲4的整數倍,最後的總大小爲4 * 4 = 16字節。get
說明:C/C++中以必定區域內的位(bit)爲單位來表示的數據成爲位域,位域必須指明具體的數目,位域的做用主要是節省內存資源,使數據結構更緊湊。
1. 取地址操做符&不能應用在位域字段上;
2. 位域字段不能是類的靜態成員;
3. 位域字段在內存中的位置是按照從低位向高位的順序放置的;
4. 位域的對齊
a. 若是相鄰位域字段的類型相同,且其位寬之和小於類型的sizeof大小,則後面的字段將緊鄰前一個字段存儲,直到不能容納爲止;
b. 若是相鄰位域字段的類型相同,但其位寬之和大於類型的sizeof大小,則後面的字段將重新的存儲單元開始,其偏移量爲其類型大小的整數倍;
c.若是相鄰的兩個位域字段的類型不一樣,則各個編譯器的具體實現有差別,VC6採起不壓縮方式,採用第一節說的字節對齊方式進行。
d. 整個結構體的總大小採用字節對齊方式的第4點。
e. 若是位域字段之間穿插着非位域字段,則不進行壓縮,採用第一節說的字節對齊方式進行。
f. 無名的位域不能使用,只能用於填充,位寬爲0表示強制下一位域對齊到當前類型的邊界。
例如:
///< 假設按4字節對齊
#pragma pack(push, 4)
struct data { short a : 7; //從第1個字節開始,佔1字節,使用7位 short b : 5; //從第2個字節開始,佔1字節,使用5位 long long e : 4; //與上個類型不一致,e的有效對齊參數值是min(8,4)爲4字節,因此從第5個字節開始,佔8字節,使用4位 char f : 5; //與上個類型不一致,f的有效對齊參數值是min(1,4)爲1字節,因此從第13個字節開始,佔1字節,使用1位 };
它們的和爲1字節(a)+1字節(b)+2字節(填充)+8字節(e)+1字節(f)=13字節。
由於總體結構體還須要進行對齊,結構成員最大有效對齊參數值爲4,因此整個結構爲4的整數倍,最後的總大小爲4 * 4 = 16字節。
///< 假設按4字節對齊
#pragma pack(push, 4) struct bits8 { short a : 3; //從第1個字節開始,佔1字節,使用3位 short : 0; //佔位,佔21位,強制下一類型對齊到邊界 char : 3; //佔位,從第3個字節開始,佔3位 char b : 5; //從第3字節第4位開始,使用5位 int i : 4; //從第5個字節開始,佔4字節,使用4位 };
它們的和爲2字節(a)+1字節(b)+1字節(填充)+4字節(i)=8字節。
由於總體結構體還須要進行對齊,結構成員最大有效對齊參數值爲4,因此整個結構爲4的整數倍,知足條件,最後的總大小爲8字節。
參考:
https://www.cnblogs.com/pure/archive/2013/04/22/3034818.html
https://jocent.me/2017/07/24/bit-field-detail.html