本文為轉(zhuǎn)載,原文地址:http://11142019.blog.51cto.com/11132019/1766032
空結(jié)構(gòu)體:對(duì)于空結(jié)構(gòu)體,就是只有結(jié)構(gòu)體這個(gè)模子,但里面卻沒有元素的結(jié)構(gòu)體。
例:
typedef struct student
{
}std;
這種空結(jié)構(gòu)體的模子占一個(gè)字節(jié),sizeof(std)=1。
柔性數(shù)組:
結(jié)構(gòu)體中最后一個(gè)元素可以是一個(gè)大小未知的數(shù)組,稱作柔性數(shù)組成員,規(guī)定柔性數(shù)組前面至少有一個(gè)元素.
typedef struct student
{
int i;
char arr[]; //柔性數(shù)組成員
}std;
sizeof(std)=4;
sizeof求取該結(jié)構(gòu)體大小是不包含柔性數(shù)組的大小,柔性數(shù)組不管有沒有大小都不計(jì)入結(jié)構(gòu)體的大小,可以通過動(dòng)態(tài)內(nèi)存為它實(shí)現(xiàn)內(nèi)存分配。

內(nèi)存對(duì)齊:
對(duì)于字(自然邊界是偶數(shù)地址),雙字(自然邊界是能被4整除的地址),四字(自然邊界是能被8整除的地址)本身就是對(duì)齊的。為什么要對(duì)齊呢?這是因?yàn)閷?duì)于對(duì)齊的內(nèi)存只需要一次內(nèi)存訪問,對(duì)于未對(duì)齊的內(nèi)存,處理器要兩次內(nèi)存訪問。

未對(duì)齊:一個(gè)字或者雙字跨越了4字節(jié)邊界,或者雙字跨越了8字節(jié)邊界,需要兩次內(nèi)存訪問。
對(duì)于結(jié)構(gòu)體,聯(lián)合體在計(jì)算其大小時(shí)要考慮其內(nèi)存對(duì)齊,以結(jié)構(gòu)中所占字節(jié)數(shù)最大的類型類型對(duì)齊。
例:
struct test
{
char a1;
short b2;
char c3;
int d4;
};
因?yàn)槠渲衖nt類型所占字節(jié)最多,所以以4字節(jié)對(duì)齊,內(nèi)存分配方式如下,總共占12個(gè)字節(jié):

分析:因?yàn)橐?字節(jié)對(duì)齊,首先char a1占一個(gè)字節(jié)存到00處,short b2 是字占兩個(gè)字節(jié) ,以偶數(shù)地址對(duì)齊,所以不能直接存到01 02 上,而應(yīng)該存到02 03上,而空出來的01就會(huì)被浪費(fèi)掉。同理,當(dāng)char c3存到04上后,對(duì)于int i,雙字必須要存到4的倍數(shù)的地址上,就只能存到08 09 0a 0b上,空出來的05 06 07會(huì)被浪費(fèi)掉。
struct test
{
char a1;
char c3;
short b2;
int d4;
};
同樣的,以4字節(jié)對(duì)齊,總共占8個(gè)字節(jié):
這是因?yàn)閍1存到00,c3存到01,b2剛好存到02 03上,以偶數(shù)地址對(duì)齊,d4也剛好從04開始存儲(chǔ),以4字節(jié)對(duì)齊,沒有浪費(fèi)內(nèi)存。
大端字節(jié)序:高字節(jié)存儲(chǔ)在低地址,低字節(jié)存儲(chǔ)在高字節(jié)處
小端字節(jié)序:低字節(jié)存儲(chǔ)在低地址,高字節(jié)存儲(chǔ)在高地址處
計(jì)算機(jī)的最小存儲(chǔ)單位是字節(jié),一個(gè)字節(jié)占8bit位。
以int為例:
例如:1的二進(jìn)制碼是
00000000 00000000 00000000 00000001
寫成十六進(jìn)制形式 :00 00 00 01這就代表了4個(gè)字節(jié),而內(nèi)存是從低地址到高地址的,這樣就產(chǎn)生了兩種存儲(chǔ)方式。

因?yàn)榇鎯?chǔ)方式方式的不同,讀取時(shí)也就產(chǎn)生了兩種方式。
一般讀取是從低地址向高地址讀取,為了將存儲(chǔ)與讀取統(tǒng)一取來,所以采用小端存儲(chǔ),這樣的話,低字節(jié)存到低地址,高字節(jié)存到高地址。
驗(yàn)證方法:
1、可以聲明一個(gè)int a=1,再聲明一個(gè)char *p=&a;因?yàn)閍占4個(gè)字節(jié),char 一次向后訪問一個(gè)字節(jié),所以如果是小端的話在電腦上輸出p應(yīng)該是1.
2、也可以用union,因?yàn)閡nion是內(nèi)存公用,所以聲明一個(gè)int a,char c;對(duì)a賦值為1,輸出c觀察結(jié)果。
有些問題如果不考慮大小端的話是根本想不明白的。