为什么可以在说明符 %d 中转换类型 char?

the reason why type char can be converted in specifier %d?

提问人:kanoo12 提问时间:8/8/2023 最后编辑:kanoo12 更新时间:8/8/2023 访问量:44

问:

我突然注意到我使用了带有 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

但是每当我像上面一样编译代码时,我总是得到预期的输出。

我不应该总是期待这个输出吗?

或者,当传递给函数的参数时,IS 类型 char 扩展为 int 类型?所以它可以是 65,我可以使用类型为 char 的说明符吗?%d

C 字符 格式说明符 转换说明符

评论

2赞 Eugene Sh. 8/8/2023
printf采用可变参数,而可变参数正在进行默认升级。因为它变成了.6.5.2.2p6 和 p7charint
1赞 Gerhardh 8/8/2023
您将看到值的相同行为。或者使用提升为 的值。shortfloatdouble
0赞 273K 8/8/2023
这回答了你的问题吗?隐式类型升级规则

答:

1赞 Eric Postpischil 8/8/2023 #1

C 2018 6.5.2.2 7说:

...如果表示被调用函数 [ 是该表达式] 的表达式具有包含原型 [it does] 的类型,则参数将隐式转换为相应参数的类型,就像通过赋值一样,将每个参数的类型作为其声明类型的非限定版本。函数原型声明器中的省略号表示法会导致参数类型转换在上次声明的参数之后停止。默认参数升级是对尾随参数执行的。printf

printf,所以,在 中,参数对应于参数,而 对应于 ,使其成为尾随参数的一部分。因此,默认参数升级是对其执行的。这些在 6.5.2.2 6 中指定:int printf(const char * restrict format, ...);printf("%d\n", a);"%d"formata...

...对每个参数执行整数升级,并且具有 type 的参数将提升为 。这些称为默认参数升级floatdouble

整数升级在 6.3.1.1 2 中指定:

...如果 可以表示原始类型的所有值(对于位域,受宽度限制),则该值将转换为 ;否则,它将转换为 .这些称为整数促销...intintunsigned int

因此,您的参数会自动转换为 ,因此它是 的正确类型。charaint%d