本文為轉(zhuǎn)載球碉,原文地址:http://11142019.blog.51cto.com/11132019/1766032
空結(jié)構(gòu)體:對于空結(jié)構(gòu)體撞蜂,就是只有結(jié)構(gòu)體這個模子盲镶,但里面卻沒有元素的結(jié)構(gòu)體。
例:
typedef struct student
{
}std谅摄;
這種空結(jié)構(gòu)體的模子占一個字節(jié)徒河,sizeof(std)=1。
柔性數(shù)組:
結(jié)構(gòu)體中最后一個元素可以是一個大小未知的數(shù)組送漠,稱作柔性數(shù)組成員顽照,規(guī)定柔性數(shù)組前面至少有一個元素.
typedef struct student
{
int i;
char arr[]; //柔性數(shù)組成員
}std;
sizeof(std)=4;
sizeof求取該結(jié)構(gòu)體大小是不包含柔性數(shù)組的大小闽寡,柔性數(shù)組不管有沒有大小都不計入結(jié)構(gòu)體的大小代兵,可以通過動態(tài)內(nèi)存為它實現(xiàn)內(nèi)存分配。
內(nèi)存對齊:
對于字(自然邊界是偶數(shù)地址)爷狈,雙字(自然邊界是能被4整除的地址)植影,四字(自然邊界是能被8整除的地址)本身就是對齊的。為什么要對齊呢涎永?這是因為對于對齊的內(nèi)存只需要一次內(nèi)存訪問思币,對于未對齊的內(nèi)存,處理器要兩次內(nèi)存訪問羡微。
未對齊:一個字或者雙字跨越了4字節(jié)邊界谷饿,或者雙字跨越了8字節(jié)邊界,需要兩次內(nèi)存訪問妈倔。
對于結(jié)構(gòu)體博投,聯(lián)合體在計算其大小時要考慮其內(nèi)存對齊,以結(jié)構(gòu)中所占字節(jié)數(shù)最大的類型類型對齊。
例:
struct test
{
char a1;
short b2;
char c3;
int d4;
};
因為其中int類型所占字節(jié)最多盯蝴,所以以4字節(jié)對齊毅哗,內(nèi)存分配方式如下,總共占12個字節(jié):
分析:因為以4字節(jié)對齊捧挺,首先char a1占一個字節(jié)存到00處虑绵,short b2 是字占兩個字節(jié) ,以偶數(shù)地址對齊闽烙,所以不能直接存到01 02 上翅睛,而應該存到02 03上,而空出來的01就會被浪費掉。同理宏所,當char c3存到04上后,對于int i摊溶,雙字必須要存到4的倍數(shù)的地址上爬骤,就只能存到08 09 0a 0b上,空出來的05 06 07會被浪費掉莫换。
struct test
{
char a1;
char c3;
short b2;
int d4;
};
同樣的霞玄,以4字節(jié)對齊,總共占8個字節(jié):
這是因為a1存到00拉岁,c3存到01坷剧,b2剛好存到02 03上,以偶數(shù)地址對齊喊暖,d4也剛好從04開始存儲惫企,以4字節(jié)對齊,沒有浪費內(nèi)存陵叽。
大端字節(jié)序:高字節(jié)存儲在低地址狞尔,低字節(jié)存儲在高字節(jié)處
小端字節(jié)序:低字節(jié)存儲在低地址,高字節(jié)存儲在高地址處
計算機的最小存儲單位是字節(jié)巩掺,一個字節(jié)占8bit位偏序。
以int為例:
例如:1的二進制碼是
00000000 00000000 00000000 00000001
寫成十六進制形式 :00 00 00 01這就代表了4個字節(jié),而內(nèi)存是從低地址到高地址的胖替,這樣就產(chǎn)生了兩種存儲方式研儒。
因為存儲方式方式的不同,讀取時也就產(chǎn)生了兩種方式独令。
一般讀取是從低地址向高地址讀取端朵,為了將存儲與讀取統(tǒng)一取來,所以采用小端存儲记焊,這樣的話逸月,低字節(jié)存到低地址,高字節(jié)存到高地址遍膜。
驗證方法:
1碗硬、可以聲明一個int a=1,再聲明一個char *p=&a;因為a占4個字節(jié)瓢颅,char 一次向后訪問一個字節(jié)恩尾,所以如果是小端的話在電腦上輸出p應該是1.
2、也可以用union,因為union是內(nèi)存公用挽懦,所以聲明一個int a翰意,char c;對a賦值為1,輸出c觀察結(jié)果。
有些問題如果不考慮大小端的話是根本想不明白的冀偶。