我已经看到很多问题,但我仍然有问题或误解。标准说: 第7.21.6 / 9节说
“如果转换规范无效,则行为未定义。 如果任何参数不是相应的正确类型 转换规范,行为未定义。“。
char c='a';
printf("%d",c); // is this undefined behavior
我知道完美的格式必须是printf("%hhd",c);
或printf("%c",c);
但我想知道究竟发生了什么?
在哪些情况下促销会完全上升或下降?
scanf
是否相同?
答案 0 :(得分:7)
不,您的示例不是未定义的行为。 char
到int
是默认参数促销之一。根据规范, 6.5.2.2函数调用,第6段:
对每个参数执行整数提升,并将类型为
float
的参数提升为double
整数促销(来自 6.3.1.1布尔,字符和整数,第2段):
如果
int
可以表示原始类型的所有值(受宽度限制,对于位字段),该值将转换为 {{ 1}} 强>;否则,它会转换为int
。这些被称为整数促销。所有其他类型都不会被整数促销更改。
答案 1 :(得分:2)
一步一步。 (A C
回答)
'a'
是字符常量(C11 6.4.4.4 1)。 “整数字符常量的类型为int
。” (§6.4.4.410)。将int
分配给char
可能不适合,但该编译器知道常量的值并知道该值可表示为char
。没有警告,没有问题。
char c='a';
代码正在将char
传递给具有...
的函数,并且不会对参数进行原型化,因此应用“如果表示被调用函数的表达式具有不包含原型,对每个参数执行整数提升,...... §6.5.2.2 6
,c
在int
的通常情况下被提升为CHAR_MAX <= INT_MAX
。否则{{ 1}}被提升为c
。
unsigned
printf(some_format,c);
收到printf()
或int
。给定格式说明符unsigned
,代码需要"%d"
。当int
晋升为c
时,所有行为都是定义良好的行为。
int
在罕见的平台上,printf("%d",c);
被c
提升为unsigned
,CHAR_MAX > INT_MAX
的更深层部分适用:“...行为是undefined,除了以下情况: - 一个提升类型是有符号整数类型,另一个提升类型是相应的无符号整数类型,并且值可以在两种类型中表示; ...“。因此,如果§6.5.2.2 6
的值可以表示为c
,则没问题。否则,如果int
的值不在c
范围内,则使用int
是UB。需要明确的是:"%d"
甚至CHAR_MAX > INT_MAX
的平台很少见,并且会带来额外的便携性问题。
使用UCHAR_MAX > INT_MAX
并不是完美的格式。 char c; printf("%hhd",c);
最适合作为角色类型。当需要窄类型的数值时,最好使用char
或signed char
。
IMO,以高度便携的方式打印unsigned char
的数值:
char
答案 2 :(得分:0)
但我想知道究竟发生了什么?
促销int
。所以它基本上有效(&#34;有时可以工作&#34;,正如纯粹主义者所说)。
对于scanf是否相同?
scanf
使用不同故事的变量地址。当scanf
存储值时,由于变量大小不同,可能(通常会)发生内存损坏。