以下代码为何起作用?
char c = 'A';
printf("%d - size: %d", c, sizeof(c));
打印出:
65 - size: 1
为什么输出不是垃圾,因为int通常为4个字节长,我们可以清楚地看到char为1个字节长。 编译器会进行隐式对话吗?
答案 0 :(得分:5)
任何在表达式中使用的排名低于int
的整数类型都会被提升到int
或unsigned int
。 C标准的6.3.1.1p2部分对此进行了规定:
以下表达式可以在表达式中使用int或unsigned 可以使用int:
- 具有整数类型(小于int或unsigned int)的整数转换等级小于的对象或表达式 或等于int和unsigned int的等级。
- 一个类型的位域 _Bool,int,signed int或unsigned int。
如果一个int可以表示原始类型的所有值(如 受宽度限制(对于位字段),该值为 转换为一个int;否则,它将转换为无符号 诠释这些称为整数促销。
所有其他类型的整数促销均不变
在这种情况下就是这种情况,因为printf
函数在编译时并不隐式知道其参数的类型。因此,char
参数被提升为int
,并且使用%d
对其进行格式化是有效的。
答案 1 :(得分:5)
对于带有可变长度参数列表的函数(例如printf
)有一条特殊规则。在参数列表的变长部分中,所有小于int
的整数参数都提升为int
,而float
提升为double
。因此,事实证明,使用short
打印字符(或%d
)是非常好的。
这些默认参数提升最终导致了printf
中的许多异常。您可能会认为char
,short
,int
,float
和double
的正确格式说明是%hhd
,{{1} },%hd
,%d
和%f
。但是实际上,您可以摆脱%lf
,%d
,%d
,%d
和%f
的束缚。 %f
基本上忽略了浮点数的printf
修饰符,而似乎忽略了整数的l
修饰符。 (实际上,h
可以在晦涩的情况下有所作为,就像chux在评论中解释的那样。)