结构体与位域的对齐
? ? ?結(jié)構(gòu)體的對齊方式; ? ? ? ? ? 1.對于結(jié)構(gòu)體中的成員 每一個成員的地址必須是該成員類型大小的整數(shù)倍 ? ? ? ? ? 如 ? ? ? ? ?? ? ? ? ? ?? ? ? ? ? ? 編譯器這樣對齊是為了能夠更高效率的傳輸數(shù)據(jù) 但是這樣也會有一些問題 比如我們將結(jié)構(gòu)體里的數(shù)據(jù)不變 ? ? ? 但是改變它們的順序: ? ? ? ? ? ? ? ? ? ? 此時結(jié)構(gòu)體的大小變?yōu)榱? 比前面節(jié)省了四個字節(jié) 也就是說結(jié)構(gòu)體中的成員按照類型從小到大的序列是最好的 可惜編譯器不會為我們做這些? ? ? ? ? ? 結(jié)構(gòu)體成員的對齊方式使得我們在使用時要注意以下幾點: ? ? ? ? ? ?????同一個結(jié)構(gòu)體成員定義順序不同 得到的大小可能不同 ? ? ? ? ? ?????結(jié)構(gòu)體中中的成員有自己的對齊方式 因此我們不應(yīng)該有通過*(&(s.a)+1)來訪問b等類似的操作 ? ? ? ? ? ? ? ?如果結(jié)構(gòu)體ST含有靜態(tài)成員 那么靜態(tài)成員長度將不包含在sizeof(s)中 (類似C++中靜態(tài)成員屬于類) ? ? ?2.結(jié)構(gòu)體的對齊方式,結(jié)構(gòu)體的對齊字節(jié)就是結(jié)構(gòu)體中最長的成員類型長度 ? ? ? ? ? ? ? ?如對于上面定義的ST 它按照四個字節(jié)對齊 ? ? ? ? ? ? ? ?又如: ? ? ? ? ? ? ? ?? ? ? ? ? ? ST按照其中類型最長的double8字節(jié)對齊 這可以在STT中驗證(stt.s1地址最后一位為0 是8的倍數(shù))? ? ? ? ? ? STT包含ST STT的類型對齊將按照結(jié)構(gòu)體ST的對齊方式 即也為8字節(jié) 可以在STTT中驗證(&sttt.s2最后一位為8) ? ? ? ? ? 另外 對于空結(jié)構(gòu)體 它也要占用一個字節(jié)的內(nèi)存 因為編譯器要確保每一個結(jié)構(gòu)體都有唯一的地址 注意這一個字節(jié)的空間在棧中由于棧本身的對齊方式 將占用四個字節(jié)
? ? ?位域: ? ? ? ? ? 位域是指為位為單位來定義某結(jié)構(gòu)體的成員變量 它和結(jié)構(gòu)體是分不開的 ? ? ? ? ?? ? ? ? ? ? ?可見 a b c三個位段共用一個地址 但是變量i仍然其類型int的對齊方式 abc一共9位 剩余的23位并未使用 ? ? ? ? ? 位域的一些使用: ? ? ? ? ? 1.位域變量僅限整型 ? ? ? ? ? 2.位域變量的長度不能夠超過其本身類型的長度 ? ? ? ? ? 3.如果某一位域要從一個新的類型對齊處開始 可以在前面加一個長度為0的匿名位域 unsigned :0 ? ? ? ? ? 4.匿名位域長度不為0時 只起占位的作用 ? ? ? ? ? 5.一個位域必須容納在同一個其類型對齊長度內(nèi) ? ? ? ? ? 關(guān)于位域?qū)R更多資料(網(wǎng)上摘錄):
? ? ? ? ??/*************************************************************************
????????????????????C99規(guī)定int、unsigned?int和bool可以作為位域類型,但編譯器幾乎都對此作了擴展,
????????????????????允許其它類型類型的存在。
????????????????????使用位域的主要目的是壓縮存儲,其大致規(guī)則為:
????????????????????1)?如果相鄰位域字段的類型相同,且其位寬之和小于類型的sizeof大小,則后面的字段將緊鄰前一個字段存儲,直到不能容納為止;
????????????????????2)?如果相鄰位域字段的類型相同,但其位寬之和大于類型的sizeof大小,則后面的字段將從新的存儲單元開始,其偏移量為其類型大小的整數(shù)倍;(經(jīng)測試此條好像僅限于char型,整型可以跨域存儲)
????????????????????3)?如果相鄰的位域字段的類型不同,則各編譯器的具體實現(xiàn)有差異,VC6采取不壓縮方式,Dev-C++采取壓縮方式;
????????????????????4)?如果位域字段之間穿插著非位域字段,則不進行壓縮;
????????????????????5)?整個結(jié)構(gòu)體的總大小為最寬基本類型成員大小的整數(shù)倍。
***************************************************************************/
???????????????struct s1?
???????????????{?
???????????????int i: 8;?
???????????????int j: 4;?
???????????????int a: 3;?
???????????????double b;?
???????????????};?
???????????????struct s2?
???????????????{?
???????????????int i: 8;?
???????????????int j: 4;?
???????????????double b;?
???????????????int a:3;?
???????????????};?
???????????????printf("sizeof(s1)= %d\n", sizeof(s1));?
???????????????printf("sizeof(s2)= %d\n", sizeof(s2));?
???????????????result: 16, 24?
???????????????第一個結(jié)構(gòu)體中,i,j,a共占15個位,不足8個字節(jié),按double 8字節(jié)對齊,共16字節(jié)
總結(jié)
- 上一篇: libevent源码深度剖析八
- 下一篇: 简单剖析C语言中的位扩展问题