1. 程式人生 > >C++字節對齊與位域

C++字節對齊與位域

oat sizeof int long 結構 code 操作符 targe 一個

一、字節對齊:

  說明:為了提高 CPU 的存儲速度,編譯器會對 struct 和 union的存儲進行優化,即進行字節對齊。

  1. 指定對齊參數值:通過#pragma pack(push, n)設置。

  2. 自身對齊參數值:每個內部類型自身也都有一個對齊參數,一般來說這個對齊參數就是 sizeof(type) 的值,也就是char的自身對齊參數是1,short是2,int是4,float也是4,double是8等。

  3. 有效對齊參數值:內部類型的有效對齊是指它的自身對齊參數和指定對齊參數中較小的那個值;

  4. 結構體整體的有效對齊參數值:是指它的成員中,有效對齊參數最大的那個值。

例如:

///< 假設按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字節。

二、位域:

  說明:C/C++中以一定區域內的位(bit)為單位來表示的數據成為位域,位域必須指明具體的數目,位域的作用主要是節省內存資源,使數據結構更緊湊。

  1. 取地址操作符&不能應用在位域字段上;

  2. 位域字段不能是類的靜態成員;

  3. 位域字段在內存中的位置是按照從低位向高位的順序放置的;

  4. 位域的對齊

    a. 如果相鄰位域字段的類型相同,且其位寬之和小於類型的sizeof大小,則後面的字段將緊鄰前一個字段存儲,直到不能容納為止;

    b. 如果相鄰位域字段的類型相同,但其位寬之和大於類型的sizeof大小,則後面的字段將從新的存儲單元開始,其偏移量為其類型大小的整數倍;

    c.如果相鄰的兩個位域字段的類型不同,則各個編譯器的具體實現有差異,VC6采取不壓縮方式,采用第一節說的字節對齊方式進行。

    d. 整個結構體的總大小采用字節對齊方式的第4點

    e. 如果位域字段之間穿插著非位域字段,則不進行壓縮,采用第一節說的字節對齊方式進行。

例如:

///< 假設按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字節。

參考:
  https://www.cnblogs.com/pure/archive/2013/04/22/3034818.html
  https://jocent.me/2017/07/24/bit-field-detail.html

C++字節對齊與位域