一讲竿、字節(jié)對(duì)齊的規(guī)則:
1拟杉、一般設(shè)置的對(duì)齊方式為1庄涡,2,4字節(jié)對(duì)齊方式搬设。結(jié)構(gòu)的首地址必須是結(jié)構(gòu)內(nèi)最寬類(lèi)型的整數(shù)倍地址穴店;另外,結(jié)構(gòu)體的每一個(gè)成員起始地址必須是自身類(lèi)型大小的整數(shù)倍(需要特別注意的是windows下是這樣的拿穴,但在linux的gcc編譯器下最高為4字節(jié)對(duì)齊)泣洞,否則在前一類(lèi)型后補(bǔ)0;這里特別提到的是數(shù)組一定要注意默色,而且在一些編程的技巧中球凰,我們可以使用數(shù)組強(qiáng)制字節(jié)達(dá)到對(duì)齊的目的。這在網(wǎng)絡(luò)編程中是很常見(jiàn)的腿宰。
舉例:比如CHAR型占用空間為1字節(jié)呕诉,則其起始位置必須可被1整除。INT為4字節(jié)吃度,其起始位置必須被4帶隊(duì)甩挫,依次類(lèi)推。(我們假定類(lèi)或結(jié)構(gòu)體的起始位置為0位置椿每,其實(shí)編譯器是在開(kāi)辟空間時(shí)伊者,會(huì)尋找起始位置可被結(jié)構(gòu)內(nèi)最寬類(lèi)型整除的地址做為開(kāi)始地址,因此我們可以假定其為0值间护,因?yàn)檫@0值可以被任意的類(lèi)型整除亦渗。)
2、結(jié)構(gòu)體的整體大小必須可被對(duì)齊值整除汁尺,默認(rèn)4(結(jié)構(gòu)中的類(lèi)型大小都小于默認(rèn)的4)法精。
3、結(jié)構(gòu)體的整體大小必須可被本結(jié)構(gòu)內(nèi)的最寬類(lèi)型整除均函。(其實(shí)和上一條是一樣的亿虽,但這里獨(dú)立出來(lái),起注意作用苞也。比如結(jié)構(gòu)體里的有DOUBLE洛勉,那么結(jié)構(gòu)的大小最后必須可被8整除)
注意:GCC不是這樣,就是最高只能被4整除如迟。此為32位系統(tǒng)收毫,64為系統(tǒng)也會(huì)采用8整除的方式攻走。否則(2、3條)此再,編譯器會(huì)在結(jié)構(gòu)的最后添充一定的特定字符來(lái)補(bǔ)齊昔搂。
struct T
{
char ch;
double d ;
};
此結(jié)果強(qiáng)調(diào)為32系統(tǒng)在VC中是16個(gè)字節(jié),GCC中為12個(gè)字節(jié)输拇。64位依舊是16個(gè)字節(jié)
4摘符、對(duì)于結(jié)構(gòu)體內(nèi)嵌套結(jié)構(gòu)體的形勢(shì),規(guī)定是必須按照基本數(shù)據(jù)類(lèi)型來(lái)定義策吠,而不能以嵌套結(jié)構(gòu)大小來(lái)做為上三種使用的基準(zhǔn)逛裤。(總結(jié))結(jié)構(gòu)體可以處理成char類(lèi)型。
二猴抹、舉例:
struct A
{
??int a;?
??char b;
??short c;
};//8
struct B
{
??char b;
??int a;
??short c;
};// 12
struct C
{
??double t;
??char b;
??int a;
??short c;
}; //24
struct D
{
??char b;
??double t;
??int a;
??short c;
};//24
在VC中带族,SIZEOF這四個(gè)結(jié)構(gòu)體,分別為:8蟀给、12蝙砌、24、24跋理;
我們先談第一個(gè)择克,(說(shuō)明一下,在考慮結(jié)構(gòu)體大小時(shí)薪介,我們基本可以忽略起始地址的問(wèn)題祠饺,因?yàn)檫@個(gè)編
譯器會(huì)自動(dòng)為我們做好越驻,見(jiàn)上面的說(shuō)明)汁政,結(jié)構(gòu)體內(nèi)首先是一個(gè)INT的4字節(jié),起始地址假定為0缀旁,整除4记劈,其小于等于默認(rèn)的4字節(jié)對(duì)齊且0為4(INT的占用空間)的整數(shù)倍,所以并巍,其占四個(gè)字節(jié)目木;其后為起始地址為5,空間為1個(gè)字節(jié)的CHAR懊渡,小于4且5為1(CHAR占用空間)的整數(shù)倍刽射,故占用1個(gè)字節(jié),然后是一個(gè)起始地址為5占2個(gè)字節(jié)的SHORT剃执,其小于4誓禁,但5不為2位數(shù),故補(bǔ)齊一個(gè)字節(jié)肾档,從第6個(gè)字節(jié)開(kāi)始摹恰,占2字節(jié)空間辫继。所以共占用4+1+1(補(bǔ))+2=8;8/4=2俗慈;整除姑宽,故占用8字節(jié)空間。
再談第2個(gè)闺阱,CHAR不用解釋?zhuān)加幸粋€(gè)字節(jié)空間炮车,且可以被0地址整除。而INT則占4字節(jié)空間酣溃,所以其必須在CHAR后補(bǔ)齊3字節(jié)示血,到第四個(gè)字節(jié),才是INT的真正地址救拉。SHORT也不用說(shuō)难审,所以共占有:1+3(補(bǔ))+4+2=10個(gè)字節(jié),但10不能整除4亿絮,所以要在結(jié)構(gòu)體最后補(bǔ)齊2字節(jié)告喊。故實(shí)際占有10+2=
12個(gè)字節(jié)。
談第三個(gè)派昧,C結(jié)構(gòu)體只是在B結(jié)構(gòu)體前加了一個(gè)DOUBLE黔姜,其它都一樣,按說(shuō)應(yīng)該是20個(gè)字節(jié)啊蒂萎,但注意我們上面規(guī)則的第3條秆吵。必須是最寬類(lèi)型的整數(shù)倍,一定要分清五慈,所以得補(bǔ)齊到24纳寂,D結(jié)構(gòu)體類(lèi)似,不再講泻拦。
Linux系統(tǒng)32位與64位GCC編譯器基本數(shù)據(jù)類(lèi)型長(zhǎng)度對(duì)照表
實(shí)例參考:
GNU C擴(kuò)展的__attribute__ 機(jī)制被用來(lái)設(shè)置函數(shù)毙芜、變量、類(lèi)型的屬性争拐,其用得較多的是處理字節(jié)對(duì)齊的問(wèn)題腋粥。
__attribute__ 的語(yǔ)法為:
__attribute__ ((語(yǔ)法列表))參數(shù)aligned(number) [number為最小對(duì)齊的字節(jié)數(shù)]是用得較多的一個(gè)。
另一個(gè)是參數(shù)packed 表示“使用最小對(duì)齊”方式架曹,即對(duì)變量是字節(jié)對(duì)齊隘冲,對(duì)于域是位對(duì)齊。
#include
struct
A{
char a;????//1Byte
int b;?????//4B
unsigned short c;//2B
long d;????//4B
unsigned long long e; //8B
char 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 = %d\n",
?sizeof(struct A), sizeof(struct B), sizeof(struct C), sizeof(struct D), sizeof(struct E),??sizeof(struct F),sizeof(struct H));
return 0;
}
結(jié)果:
$ ./aligned32
A = 28, B = 32, C = 28, D = 28, E = 32, F = 20, H = 12
$ ./aligned64
A = 40, B = 48, C = 40, D = 40, E = 40, F = 24, H = 16
分享一些C語(yǔ)言相關(guān)的資料
結(jié)構(gòu)體普及與應(yīng)用
http://www.makeru.com.cn/live/5413_1909.html?s=45051
C語(yǔ)言玩轉(zhuǎn)鏈表
http://www.makeru.com.cn/live/1392_338.html?s=45051
必備Linux命令和C語(yǔ)言基礎(chǔ)
http://www.makeru.com.cn/video/1862.html?s=45051
釋放潛能:學(xué)習(xí)效率提升绑雄、編程能力提升