關(guān)注「嵌入式大雜燴」,星標(biāo)公眾號,一起進(jìn)步!來源:嵌入式Linux系統(tǒng)開發(fā)
Linux 上可用的 C 編譯器是 GNU C 編譯器,它建立在自由軟件基金會的編程許可證的基礎(chǔ)上,因此可以自由發(fā)布。GNU C對標(biāo)準(zhǔn)C進(jìn)行一系列擴(kuò)展,以增強(qiáng)標(biāo)準(zhǔn)C的功能。
1.零長度和變量長度數(shù)組
GNU C允許使用零長度數(shù)組,在定義變長對象的頭結(jié)構(gòu)時,這個特性非常有用。例如:
struct?var_data?{?
????int?len;?
????char?data[0];?
};
char data[0]僅僅意味著程序中通過var_data結(jié)構(gòu)體實例的data[index]成員可以訪問len之后的第index個地址,它并 沒有為data[]數(shù)組分配內(nèi)存,因此sizeof(struct var_data)=sizeof(int)。假設(shè)struct var_data的數(shù)據(jù)域就保存在struct var_data緊接著的內(nèi)存區(qū)域中,則通過如下代碼可以遍歷這些數(shù)據(jù):
struct?var_data?s;?
...?
for?(i?=?0;?i?????printf("x",?s.data[i]);
GNU C中也可以使用1個變量定義數(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這樣的語法,區(qū)間[x,y]中的數(shù)都會滿足這個case的條件,請看下面的代碼:
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'等價于標(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.語句表達(dá)式
GNU C把包含在括號中的復(fù)合語句看成是一個表達(dá)式,稱為語句表達(dá)式,它可以出現(xiàn)在任何允許表達(dá)式的地 方。我們可以在語句表達(dá)式中使用原本只能在復(fù)合語句中使用的循環(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);
因為重新定義了__xx和__y這兩個局部變量,所以用上述方式定義的宏將不會有副作用。在標(biāo)準(zhǔn)C中,對應(yīng)的如 下宏則會產(chǎn)生副作用:
#define?min(x,y)?((x)?(y)?(x)?:?(y))
代碼min( ia, ib)會展開為(( ia)<( ib)( ia):( ib)),傳入宏的“參數(shù)”增加兩次。
4.typeof關(guān)鍵字
typeof(x)語句可以獲得x的類型,因此,可以借助typeof重新定義min這個宏:
#define?min(x,y)?({?\?
const?typeof(x)?_x?=?(x);?\?
const?typeof(y)?_y?=?(y);?\?
(void)?(