掌握C語(yǔ)言必知要點(diǎn)(續(xù))
8、邊界對(duì)齊
本文引用地址:http://www.ex-cimer.com/article/266192.htmCPU在單位時(shí)間內(nèi)(同一時(shí)間)能一次處理的二進(jìn)制數(shù)的位數(shù)叫字長(zhǎng)。處理字長(zhǎng)為8位數(shù)據(jù)的CPU通常就叫8位的CPU, 當(dāng)前的CPU大部分是32位的CPU,如果某臺(tái)機(jī)器的字長(zhǎng)為4個(gè)字節(jié)(也就是32位),那么下面的結(jié)構(gòu)體會(huì)占用多少內(nèi)存空間呢?
struct StrA{
int a;
char b;
short c;
char d;
};
如果你的答案是12字節(jié),恭喜你!答對(duì)了。這個(gè)結(jié)構(gòu)在內(nèi)存中的存儲(chǔ)如下圖所示:
a為int型,占4個(gè)字節(jié)(0-3),b為char型,占一個(gè)字節(jié)(4),c就要注意了,short型占2個(gè)字節(jié),但是不能從5號(hào)位存儲(chǔ),偏移量必須為2的整數(shù)倍位置,所以,從6號(hào)位置開始,占據(jù)6和7號(hào)位,d為char型,只需占用8號(hào)位即可,但是由于機(jī)器字長(zhǎng)為4個(gè)字節(jié),當(dāng)下一個(gè)結(jié)構(gòu)存儲(chǔ)時(shí),不能從9號(hào)位開始,需從12號(hào)位開始,也就是說(shuō)9、10、11號(hào)位也被浪費(fèi)掉。
簡(jiǎn)單來(lái)說(shuō)可以這樣算,在成員變量所占字節(jié)數(shù)和機(jī)器字長(zhǎng)中選擇小的一個(gè),并按該字節(jié)數(shù)對(duì)齊,比如c占2個(gè)字節(jié),那么在存儲(chǔ)它時(shí),就按2字節(jié)對(duì)齊,存儲(chǔ)c的位置必須是2的整數(shù)倍,b和d占1字節(jié),按1字節(jié)對(duì)齊,所以實(shí)際上結(jié)構(gòu)體共占用了9個(gè)字節(jié),最后一步,需要按照機(jī)器字長(zhǎng)進(jìn)行圓整,因?yàn)樽珠L(zhǎng)為4字節(jié),所以結(jié)構(gòu)體占用字節(jié)數(shù)必須為4的整數(shù)倍,最終占了12字節(jié)的內(nèi)存。
再看下面這個(gè)例子,占用了多少字節(jié)呢?
struct StrB{
int a;
short c;
char b;
char d;
};
答案是:8個(gè)。兩個(gè)結(jié)構(gòu)存儲(chǔ)的內(nèi)容完全相同,知識(shí)調(diào)整了成員b和c的順序,但是卻節(jié)省了33%的空間。
9、再說(shuō)static
Static可以用來(lái)修飾全局變量、局部變量和函數(shù)。下面注意來(lái)講述:
(1)被static修飾的全局變量稱為靜態(tài)全局變量,它與普通全局變量的區(qū)別在于,“普通全局變量穿上static外衣后,它就變成了新娘,已心有所屬,只能被定義它的源文件(新郎)中的變量或函數(shù)訪問(wèn)。”而其它文件內(nèi)的函數(shù)是無(wú)法訪問(wèn)它的。
(2)普通的局部變量在??臻g上分配,這個(gè)局部變量所在的函數(shù)被多次調(diào)用時(shí),每次調(diào)用這個(gè)局部變量在棧上的位置都不一定相同。而且只有當(dāng)函數(shù)被調(diào)用時(shí)普通局部變量才被創(chuàng)建,函數(shù)調(diào)用完畢則銷毀。
被static修飾的局部變量稱作靜態(tài)局部變量,它雖然是局部的,但是在程序的整個(gè)生命周期中存在。和局部變量一樣,只能在函數(shù)內(nèi)部訪問(wèn),不能被其他函數(shù)和源文件訪問(wèn),靜態(tài)局部變量如果沒(méi)有被用戶初始化,則會(huì)被編譯器自動(dòng)賦值為0,因?yàn)槠洳粫?huì)被銷毀,所以以后再調(diào)用靜態(tài)局部變量的時(shí)候都用上次修改過(guò)后的值。
(3)當(dāng)函數(shù)被static修飾后,就只能被當(dāng)前文件中的被訪問(wèn),即使其它文件中含有相同名稱的函數(shù),也不會(huì)發(fā)生沖突。所以它很好地解決不同原文件中函數(shù)同名的問(wèn)題。
10、函數(shù)指針數(shù)組
數(shù)組名是數(shù)組的第一個(gè)元素在內(nèi)存中的地址,函數(shù)名是執(zhí)行這個(gè)函數(shù)任務(wù)的代碼在內(nèi)存中的起始地址。函數(shù)指針可以指向函數(shù)的起始地址,因此函數(shù)名可通過(guò)函數(shù)指針加以保存。那么也能夠定義一個(gè)數(shù)組保存若干個(gè)函數(shù)名,這就是函數(shù)指針數(shù)組。但是這若干個(gè)需要通過(guò)函數(shù)指針數(shù)組保存的函數(shù)必須有相同的輸入、輸出值。
函數(shù)指針數(shù)組用在這種情況下,當(dāng)我們要根據(jù)一個(gè)變量值來(lái)決定執(zhí)行某個(gè)函數(shù)時(shí),我們可以使用switch-case語(yǔ)句來(lái)做,可是當(dāng)要處理的情況較多時(shí),比如100種情況,那就需要寫100個(gè)case來(lái)選擇,但是你大可不必這樣做,這時(shí)候函數(shù)指針數(shù)組就派上用場(chǎng)了。具體如何使用呢,舉例如下:
首先要定義100個(gè)函數(shù):
Int Func1(int,int);
.
.
.
Int Func100(int,int);
其次定義函數(shù)指針數(shù)組,并給數(shù)組賦值。
Int (*func[100])(int,int)={ Func1,F(xiàn)unc2,…Func100};
最后,根據(jù)變量var的值來(lái)決定執(zhí)行那個(gè)函數(shù),并將執(zhí)行結(jié)果返回給result。
Result = func[var](var1,var2);
根據(jù)var從數(shù)組中選擇正確的函數(shù)指針,并調(diào)用相應(yīng)函數(shù)來(lái)執(zhí)行,代碼量大大減少,執(zhí)行效率較高。
C的指針很靈活,對(duì)指針的限制也較少,所以程序員在使用指針時(shí)需加倍小心。Pascal語(yǔ)言的指針哲學(xué):“使用錘子可能會(huì)傷到你自己,所以我們不給你錘子”。而C語(yǔ)言則是:“給你錘子,實(shí)際上你可以使用好錘子,祝你好運(yùn)!”。
So, good luck!!!
c語(yǔ)言相關(guān)文章:c語(yǔ)言教程
評(píng)論