零基礎(chǔ)入門(mén)之結(jié)構(gòu)體字節(jié)對(duì)齊

一讲竿、字節(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í)效率提升绑雄、編程能力提升

http://www.makeru.com.cn/live/3507_1276.html?s=45051

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末展辞,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子绳慎,更是在濱河造成了極大的恐慌纵竖,老刑警劉巖漠烧,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異靡砌,居然都是意外死亡已脓,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)通殃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)度液,“玉大人,你說(shuō)我怎么就攤上這事画舌《榈#” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵曲聂,是天一觀的道長(zhǎng)霹购。 經(jīng)常有香客問(wèn)我,道長(zhǎng)朋腋,這世上最難降的妖魔是什么齐疙? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮旭咽,結(jié)果婚禮上贞奋,老公的妹妹穿的比我還像新娘。我一直安慰自己穷绵,他們只是感情好轿塔,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著仲墨,像睡著了一般勾缭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宗收,一...
    開(kāi)封第一講書(shū)人閱讀 49,031評(píng)論 1 285
  • 那天漫拭,我揣著相機(jī)與錄音,去河邊找鬼混稽。 笑死,一個(gè)胖子當(dāng)著我的面吹牛审胚,可吹牛的內(nèi)容都是我干的匈勋。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼膳叨,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼洽洁!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起菲嘴,我...
    開(kāi)封第一講書(shū)人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤饿自,失蹤者是張志新(化名)和其女友劉穎汰翠,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體昭雌,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡复唤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了烛卧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片佛纫。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖总放,靈堂內(nèi)的尸體忽然破棺而出呈宇,到底是詐尸還是另有隱情,我是刑警寧澤局雄,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布甥啄,位于F島的核電站,受9級(jí)特大地震影響炬搭,放射性物質(zhì)發(fā)生泄漏型豁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一尚蝌、第九天 我趴在偏房一處隱蔽的房頂上張望迎变。 院中可真熱鬧,春花似錦飘言、人聲如沸衣形。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)谆吴。三九已至,卻和暖如春苛预,著一層夾襖步出監(jiān)牢的瞬間句狼,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工热某, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留腻菇,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓昔馋,卻偏偏與公主長(zhǎng)得像筹吐,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子秘遏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容