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