我突然注意到我使用了 char 类型的转换说明符 %d,尽管 %d 只接受 int 类型。
怎么可能?
根据c标准,转换说明符%d对应于int类型的参数。 并且 如果任何参数不是相应转换规范的正确类型, 行为未定义。
#include <stdio.h>
int main(void){
char a= 'A'; // 'A' = 65 in ASCII
printf("%c\n", a);
printf("%d\n", a);
return 0;
}
----- output -----
A
65
但是每当我像上面那样编译代码时,我总是会得到预期的输出。
我不应该总是期待这个输出吗?
或者,当传递给函数的参数时,char 类型是否扩展为 int 类型?所以它可以是 65,我可以使用说明符
%d
和 char 类型?
C 2018 6.5.2.2 7 说:
...如果表示被调用函数的表达式 [
是该表达式] 具有包含原型的类型 [确实如此],则参数会像通过赋值一样隐式转换为相应参数的类型,将每个参数的类型视为其声明类型的非限定版本。函数原型声明符中的省略号表示法会导致参数类型转换在最后一个声明的参数之后停止。默认参数提升是在尾随参数上执行的。printf
printf
被声明为 int printf(const char * restrict format, ...);
,因此,在 printf("%d\n", a);
中,"%d"
参数对应于 format
参数,a
对应于 ...
,使其成为尾随参数的一部分。因此对其执行默认参数提升。这些在 6.5.2.2 6 中指定:
…对每个参数执行整数提升,类型为
的参数将提升为float
。这些称为 默认参数促销。double
整数提升在 6.3.1.1 2:
中指定...如果
可以表示原始类型的所有值(对于位域,受宽度限制),则该值将转换为int
;否则,它会转换为int
。这些被称为整数促销…unsigned int
因此,您的
char
参数 a
会自动转换为 int
,因此它是 %d
的正确类型。