答疑解惑 | Linux GNU C 與 ANSI C 的區(qū)別
Linux 上可用的 C 編譯器是 GNU C 編譯器,它建立在自由軟件基金會(huì)的編程許可證的基礎(chǔ)上,因此可以自由發(fā)布。GNU C對(duì)標(biāo)準(zhǔn)C進(jìn)行一系列擴(kuò)展,以增強(qiáng)標(biāo)準(zhǔn)C的功能。
1.零長(zhǎng)度和變量長(zhǎng)度數(shù)組
GNU C允許使用零長(zhǎng)度數(shù)組,在定義變長(zhǎng)對(duì)象的頭結(jié)構(gòu)時(shí),這個(gè)特性非常有用。例如:struct?var_data?{?
????int?len;?
????char?data[0];?
};
char data[0]僅僅意味著程序中通過(guò)var_data結(jié)構(gòu)體實(shí)例的data[index]成員可以訪問(wèn)len之后的第index個(gè)地址,它并 沒(méi)有為data[]數(shù)組分配內(nèi)存,因此sizeof(struct var_data)=sizeof(int)。假設(shè)struct var_data的數(shù)據(jù)域就保存在struct var_data緊接著的內(nèi)存區(qū)域中,則通過(guò)如下代碼可以遍歷這些數(shù)據(jù):struct?var_data?s;?
...?
for?(i?=?0;?i?????printf("x",?s.data[i]);
GNU C中也可以使用1個(gè)變量定義數(shù)組,例如如下代碼中定義的“double x[n]”:int?main?(int?argc,?char?*argv[])?
{?
????int?i,?n?=?argc;?
????double?x[n];?
????for?(i?=?0;?i?????????x[i]?=?i;?
????return?0;?
}
2.case范圍
GNU C支持case x…y這樣的語(yǔ)法,區(qū)間[x,y]中的數(shù)都會(huì)滿足這個(gè)case的條件,請(qǐng)看下面的代碼:switch?(ch)?{?
case?'0'...?'9':?c?-=?'0';?
????break;
case?'a'...?'f':?c?-=?'a'?-?10;?
????break;?
case?'A'...?'F':?c?-=?'A'?-?10;?
????break;?
}
代碼中的case'0'...'9'等價(jià)于標(biāo)準(zhǔn)C中的:case?'0':?case?'1':?case?'2':?case?'3':?case?'4':?
case?'5':?case?'6':?case?'7':?case?'8':?case?'9':
3.語(yǔ)句表達(dá)式
GNU C把包含在括號(hào)中的復(fù)合語(yǔ)句看成是一個(gè)表達(dá)式,稱為語(yǔ)句表達(dá)式,它可以出現(xiàn)在任何允許表達(dá)式的地 方。我們可以在語(yǔ)句表達(dá)式中使用原本只能在復(fù)合語(yǔ)句中使用的循環(huán)、局部變量等,例如:#define?min_t(type,x,y)?\?
(?{?type?_?_x?=(x);type?_?_y?=?(y);?_?_x<_?_y?_?_x:?_?_y;?})?
int?ia,?ib,?mini;?
float?fa,?fb,?minf;?
mini?=?min_t(int,?ia,?ib);?
minf?=?min_t(float,?fa,?fb);
因?yàn)橹匦露x了__xx和__y這兩個(gè)局部變量,所以用上述方式定義的宏將不會(huì)有副作用。在標(biāo)準(zhǔn)C中,對(duì)應(yīng)的如 下宏則會(huì)產(chǎn)生副作用:#define?min(x,y)?((x)?(y)?(x)?:?(y))
代碼min( ia, ib)會(huì)展開(kāi)為(( ia)<( ib)( ia):( ib)),傳入宏的“參數(shù)”增加兩次。4.typeof關(guān)鍵字
typeof(x)語(yǔ)句可以獲得x的類型,因此,可以借助typeof重新定義min這個(gè)宏:#define?min(x,y)?({?\?
const?typeof(x)?_x?=?(x);?\?
const?typeof(y)?_y?=?(y);?\?
(void)?(