C語言允許兩個(gè)不同整數(shù)類型的變量,如char類型變量與int類型變量相加。C語言標(biāo)準(zhǔn)稱之為整型提升。那么我們?nèi)绾瓮ㄟ^測(cè)試代碼知道一個(gè)表達(dá)式的類型呢?
方法1:通過泛型選擇表達(dá)式
泛型選擇表達(dá)式是C11引入的新特性,主要用于標(biāo)準(zhǔn)庫(kù),特別是數(shù)學(xué)庫(kù)來實(shí)現(xiàn)輕量級(jí)的泛化處理。言歸正傳,我們來看看如何通過泛化來得到表達(dá)式的類型。代碼如下:
#define GET_TYPE(expr) \
_Generic(expr, double: "double", float: "float", \
signed char: "schar", unsigned char: "uchar", \
int:"int", unsigned int: "uint",\
long: "long", unsigned long: "ulong", \
default: "unknown")
void test(void)
{
char c = 100;
printf("type of c+1 is %s\n", GET_TYPE(c+1));
}
用gcc 6.2.0編譯(-std設(shè)置為c11),輸出如下:
type of c+1 is int
這個(gè)方法不是十全十美。再看一個(gè)例子:
float f = 1.1;
printf("type of f+1 is %s\n", GET_TYPE(f+1));
輸出是:
type of f+1 is float
很遺憾,float的算術(shù)運(yùn)算會(huì)提升到double。所以上面的答案不對(duì)。
方法2:用gcc的format檢查
這個(gè)方法更簡(jiǎn)單,甚至都不需要運(yùn)行代碼,只需要看編譯告警。
代碼如下:
char c = 100;
printf("%s\n", (c+1));
用gcc編譯(打開編譯開關(guān)-Wformat或者-Wall),有如下編譯告警:
警告:格式 ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
從中可以得知c+1的類型是int。再看看f+1的類型是啥?
float f = 1.1;
printf("%s\n", (f+1));
編譯告警如下:
警告:格式 ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘double’ [-Wformat=]
這次對(duì)了。