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