C语言允许两个不同整数类型的变量,如char
类型变量与int
类型变量相加。C语言标准称之为整型提升。那么我们如何通过测试代码知道一个表达式的类型呢?
方法1:通过泛型选择表达式
泛型选择表达式是C11引入的新特性,主要用于标准库,特别是数学库来实现轻量级的泛化处理。言归正传,我们来看看如何通过泛化来得到表达式的类型。代码如下:
#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
设置为c11
),输出如下:
type of c+1 is int
这个方法不是十全十美。再看一个例子:
float f = 1.1;
printf("type of f+1 is %s\n", GET_TYPE(f+1));
输出是:
type of f+1 is float
很遗憾,float
的算术运算会提升到double
。所以上面的答案不对。
方法2:用gcc的format检查
这个方法更简单,甚至都不需要运行代码,只需要看编译告警。
代码如下:
char c = 100;
printf("%s\n", (c+1));
用gcc编译(打开编译开关-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=]
这次对了。