c++ 结构体地址 转换成ulong_零基础入门之结构体字节对齐
一、字節(jié)對齊的規(guī)則:
1、一般設(shè)置的對齊方式為1,2,4字節(jié)對齊方式。結(jié)構(gòu)的首地址必須是結(jié)構(gòu)內(nèi)最寬類型的整數(shù)倍地址;另外,結(jié)構(gòu)體的每一個成員起始地址必須是自身類型大小的整數(shù)倍(需要特別注意的是windows下是這樣的,但在linux的gcc編譯器下最高為4字節(jié)對齊),否則在前一類型后補0;這里特別提到的是數(shù)組一定要注意,而且在一些編程的技巧中,我們可以使用數(shù)組強制字節(jié)達(dá)到對齊的目的。這在網(wǎng)絡(luò)編程中是很常見的。
舉例:比如CHAR型占用空間為1字節(jié),則其起始位置必須可被1整除。INT為4字節(jié),其起始位置必須被4帶隊,依次類推。(我們假定類或結(jié)構(gòu)體的起始位置為0位置,其實編譯器是在開辟空間時,會尋找起始位置可被結(jié)構(gòu)內(nèi)最寬類型整除的地址做為開始地址,因此我們可以假定其為0值,因為這0值可以被任意的類型整除。)
2、結(jié)構(gòu)體的整體大小必須可被對齊值整除,默認(rèn)4(結(jié)構(gòu)中的類型大小都小于默認(rèn)的4)。
3、結(jié)構(gòu)體的整體大小必須可被本結(jié)構(gòu)內(nèi)的最寬類型整除。(其實和上一條是一樣的,但這里獨立出來,起注意作用。比如結(jié)構(gòu)體里的有DOUBLE,那么結(jié)構(gòu)的大小最后必須可被8整除)
注意:GCC不是這樣,就是最高只能被4整除。此為32位系統(tǒng),64為系統(tǒng)也會采用8整除的方式。否則(2、3條),編譯器會在結(jié)構(gòu)的最后添充一定的特定字符來補齊。
struct T{char ch;double d ;};此結(jié)果強調(diào)為32系統(tǒng)在VC中是16個字節(jié),GCC中為12個字節(jié)。64位依舊是16個字節(jié)
4、對于結(jié)構(gòu)體內(nèi)嵌套結(jié)構(gòu)體的形勢,規(guī)定是必須按照基本數(shù)據(jù)類型來定義,而不能以嵌套結(jié)構(gòu)大小來做為上三種使用的基準(zhǔn)。(總結(jié))結(jié)構(gòu)體可以處理成char類型。
二、舉例:
struct A{int a;char b;short c;}; //8struct B{char b;int a;short c;}; // 12struct C{double t;char b;int a;short c;}; //24struct D{char b;double t;int a;short c;};//24在VC中,SIZEOF這四個結(jié)構(gòu)體,分別為:8、12、24、24;
我們先談第一個,(說明一下,在考慮結(jié)構(gòu)體大小時,我們基本可以忽略起始地址的問題,因為這個編
譯器會自動為我們做好,見上面的說明),結(jié)構(gòu)體內(nèi)首先是一個INT的4字節(jié),起始地址假定為0,整除4,其小于等于默認(rèn)的4字節(jié)對齊且0為4(INT的占用空間)的整數(shù)倍,所以,其占四個字節(jié);其后為起始地址為5,空間為1個字節(jié)的CHAR,小于4且5為1(CHAR占用空間)的整數(shù)倍,故占用1個字節(jié),然后是一個起始地址為5占2個字節(jié)的SHORT,其小于4,但5不為2位數(shù),故補齊一個字節(jié),從第6個字節(jié)開始,占2字節(jié)空間。所以共占用4+1+1(補)+2=8;8/4=2;整除,故占用8字節(jié)空間。
再談第2個,CHAR不用解釋,占有一個字節(jié)空間,且可以被0地址整除。而INT則占4字節(jié)空間,所以其必須在CHAR后補齊3字節(jié),到第四個字節(jié),才是INT的真正地址。SHORT也不用說,所以共占有:1+3(補)+4+2=10個字節(jié),但10不能整除4,所以要在結(jié)構(gòu)體最后補齊2字節(jié)。故實際占有10+2= 12個字節(jié)。
談第三個,C結(jié)構(gòu)體只是在B結(jié)構(gòu)體前加了一個DOUBLE,其它都一樣,按說應(yīng)該是20個字節(jié)啊,但注意我們上面規(guī)則的第3條。必須是最寬類型的整數(shù)倍,一定要分清,所以得補齊到24,D結(jié)構(gòu)體類似,不再講。
Linux系統(tǒng)32位與64位GCC編譯器基本數(shù)據(jù)類型長度對照表
實例參考:
GNU C擴展的__attribute__ 機制被用來設(shè)置函數(shù)、變量、類型的屬性,其用得較多的是處理字節(jié)對齊的問題。
__attribute__ 的語法為:
__attribute__ ((語法列表))參數(shù)aligned(number) [number為最小對齊的字節(jié)數(shù)]是用得較多的一個。
另一個是參數(shù)packed 表示“使用最小對齊”方式,即對變量是字節(jié)對齊,對于域是位對齊。
#includestruct A{char a; //1Byteint b; //4Bunsigned short c;//2Blong d; //4Bunsigned long long e; //8Bchar f; //1B};struct B{char a;int b;unsigned short c;long d;unsigned long long e;char f;}__attribute__((aligned));struct C{char a;int b;unsigned short c;long d;unsigned long long e;char f;}__attribute__((aligned(1)));struct D{char a;int b;unsigned short c;long d;unsigned long long e;char f;}__attribute__((aligned(4)));struct E{char a;int b;unsigned short c;long d;unsigned long long e;char f;}__attribute__((aligned(8)));struct F{char a;int b;unsigned short c;long d;unsigned long long e;char f;}__attribute__((packed));struct H{char a;double b;};int main(int argc, char **argv){struct A a;struct B b;struct C c;struct D d;struct E e;struct F f;printf("A = %d, B = %d, C = %d, D = %d, E = %d, F = %d, H = %dn",sizeof(struct A), sizeof(struct B), sizeof(struct C), sizeof(struct D), sizeof(struct E), sizeof(struct F),sizeof(struct H));return 0;}結(jié)果:
$ ./aligned32A = 28, B = 32, C = 28, D = 28, E = 32, F = 20, H = 12$ ./aligned64A = 40, B = 48, C = 40, D = 40, E = 40, F = 24, H = 16分享一些C語言相關(guān)的資料便于學(xué)習(xí)參考
結(jié)構(gòu)體普及與應(yīng)用
C語言玩轉(zhuǎn)鏈表
必備Linux命令和C語言基礎(chǔ)
釋放潛能:學(xué)習(xí)效率提升、編程能力提升
總結(jié)
以上是生活随笔為你收集整理的c++ 结构体地址 转换成ulong_零基础入门之结构体字节对齐的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 爬虫单个ip代理设置_爬虫怎样设置代理i
- 下一篇: java 优先队列 用法_优先队列的基本