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