一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

結(jié)構(gòu)體對齊的具體含義|結(jié)構(gòu)體,對齊,含義,

 昵稱23617 2007-03-29

最近對結(jié)構(gòu)體對齊比較感興趣,收集了一些資料

結(jié)構(gòu)體對齊的具體含義(#pragma pack)

                                      

#pragma pack (4)
  class TestB
  {
  public:
    int aa;
    char a;
    short b;
    char c;
  };
  int nSize = sizeof(TestB);
  這里nSize結(jié)果為12,在預(yù)料之中。

  現(xiàn)在去掉第一個成員變量為如下代碼:
  #pragma pack (4)
  class TestC
  {
  public:
    char a;
    short b;
    char c;
  };
  int nSize = sizeof(TestC);
  按照正常的填充方式nSize的結(jié)果應(yīng)該是8,為什么結(jié)果顯示nSize為6呢?

事實上,很多人對#pragma pack 的理解是錯誤的。
#pragma pack 規(guī)定的對齊長度,實際使用的規(guī)則是:
結(jié)構(gòu),聯(lián)合,或者類的數(shù)據(jù)成員,第一個放在偏移為0的地方,以后每個數(shù)據(jù)成員的對齊,按照#pragma pack 指定的數(shù)值和這個數(shù)據(jù)成員自身長度中,比較小的那個進行。
也就是說,當(dāng)#pragma pack 的值等于或超過所有數(shù)據(jù)成員長度的時候,這個值的大小將不產(chǎn)生任何效果。
而結(jié)構(gòu)整體的對齊,則按照結(jié)構(gòu)體中最大的數(shù)據(jù)成員 和 #pragma pack 指定值 之間,較小的那個進行。

具體解釋
#pragma pack (4)
  class TestB
  {
  public:
    int aa; //第一個成員,放在[0,3]偏移的位置,
    char a; //第二個成員,自身長為1,#pragma pack (4),取小值,也就是1,所以這個成員按一字節(jié)對齊,放在偏移[4]的位置。
    short b; //第三個成員,自身長2,#pragma pack (4),取2,按2字節(jié)對齊,所以放在偏移[6,7]的位置。
    char c; //第四個,自身長為1,放在[8]的位置。
  };
這個類實際占據(jù)的內(nèi)存空間是9字節(jié)
類之間的對齊,是按照類內(nèi)部最大的成員的長度,和#pragma pack 規(guī)定的值之中較小的一個對齊的。
所以這個例子中,類之間對齊的長度是min(sizeof(int),4),也就是4。
9按照4字節(jié)圓整的結(jié)果是12,所以sizeof(TestB)是12。


如果
#pragma pack (2)
class TestB
  {
  public:
    int aa; //第一個成員,放在[0,3]偏移的位置,
    char a; //第二個成員,自身長為1,#pragma pack (4),取小值,也就是1,所以這個成員按一字節(jié)對齊,放在偏移[4]的位置。
    short b; //第三個成員,自身長2,#pragma pack (4),取2,按2字節(jié)對齊,所以放在偏移[6,7]的位置。
    char c; //第四個,自身長為1,放在[8]的位置。
  };
//可以看出,上面的位置完全沒有變化,只是類之間改為按2字節(jié)對齊,9按2圓整的結(jié)果是10。
//所以 sizeof(TestB)是10。

最后看原貼:
現(xiàn)在去掉第一個成員變量為如下代碼:
  #pragma pack (4)
  class TestC
  {
  public:
    char a;//第一個成員,放在[0]偏移的位置,
    short b;//第二個成員,自身長2,#pragma pack (4),取2,按2字節(jié)對齊,所以放在偏移[2,3]的位置。
    char c;//第三個,自身長為1,放在[4]的位置。
  };
//整個類的大小是5字節(jié),按照min(sizeof(short),4)字節(jié)對齊,也就是2字節(jié)對齊,結(jié)果是6
//所以sizeof(TestC)是6。

 對於位域有如下規(guī)定:

C99規(guī)定int、unsigned int和bool可以作為位域類型,但編譯器幾乎都對此作了擴展,允許其它類型類型的存在。使用位域的主要目的是壓縮存儲,其大致規(guī)則為:
    1) 如果相鄰位域字段的類型相同,且其位寬之和小于類型的sizeof大小,則后面的字段將緊鄰前一個字段存儲,直到不能容納為止;
    2) 如果相鄰位域字段的類型相同,但其位寬之和大于類型的sizeof大小,則后面的字段將從新的存儲單元開始,其偏移量為其類型大小的整數(shù)倍;
    3) 如果相鄰的位域字段的類型不同,則各編譯器的具體實現(xiàn)有差異,VC6采取不壓縮方式,Dev-C++采取壓縮方式;
    4) 如果位域字段之間穿插著非位域字段,則不進行壓縮;
    5) 整個結(jié)構(gòu)體的總大小為最寬基本類型成員大小的整數(shù)倍。

    還是讓我們來看看例子。
    示例1:
struct BF1
{
    char f1 : 3;
    char f2 : 4;
    char f3 : 5;
};
    其內(nèi)存布局為:
|_f1__|__f2__|_|____f3___|____|
|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
0 3 7 8 1316
    位域類型為char,第1個字節(jié)僅能容納下f1和f2,所以f2被壓縮到第1個字節(jié)中,而f3只
能從下一個字節(jié)開始。因此sizeof(BF1)的結(jié)果為2。

    示例2:
struct BF2
{
    char f1 : 3;
    short f2 : 4;
    char f3 : 5;
};
    由于相鄰位域類型不同,在VC6中其sizeof為6,在Dev-C++中為2。

    示例3:
struct BF3
{
    char f1 : 3;
    char f2;
    char f3 : 5;
};
    非位域字段穿插在其中,不會產(chǎn)生壓縮,在VC6和Dev-C++中得到的大小均為3。


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    欧美人与动牲交a精品| 国产成人精品综合久久久看| 成人国产一区二区三区精品麻豆 | 欧美久久一区二区精品| 内射精子视频欧美一区二区| 好吊日在线视频免费观看| 欧美人妻免费一区二区三区| 亚洲香艳网久久五月婷婷| 懂色一区二区三区四区| 日本午夜精品视频在线观看| 日本一二三区不卡免费| 日本不卡在线视频你懂的| 大伊香蕉一区二区三区| 欧美日韩亚洲巨色人妻| 扒开腿狂躁女人爽出白浆av| 日韩午夜老司机免费视频| 国产成人亚洲综合色就色| 免费观看日韩一级黄色大片| 欧美午夜一区二区福利视频| 国自产拍偷拍福利精品图片| 欧美成人国产精品高清| 欧美在线视频一区观看| 久久黄片免费播放大全| 日本女优一色一伦一区二区三区| 国产精品一区二区丝袜| 国产女优视频一区二区| 亚洲中文字幕在线观看黑人| 日韩一区欧美二区国产| 亚洲欧美日韩网友自拍| 黄色片一区二区在线观看| 91亚洲国产—区=区a| 这里只有九九热精品视频| 欧美尤物在线观看西比尔| 女人高潮被爽到呻吟在线观看| 91亚洲国产—区=区a| 日韩精品区欧美在线一区| 日韩欧美一区二区不卡看片| 日本一区不卡在线观看| 日韩和欧美的一区二区三区| 丰满的人妻一区二区三区| 欧洲偷拍视频中文字幕|