了解printf?

时间:2016-08-08 17:08:58

标签: c

我已经看到很多问题,但我仍然有问题或误解。标准说: 第7.21.6 / 9节说

  

“如果转换规范无效,则行为未定义。   如果任何参数不是相应的正确类型   转换规范,行为未定义。“。

char c='a';
printf("%d",c); // is this undefined behavior

我知道完美的格式必须是printf("%hhd",c);printf("%c",c);

但我想知道究竟发生了什么?

在哪些情况下促销会完全上升或下降?

scanf是否相同?

3 个答案:

答案 0 :(得分:7)

不,您的示例不是未定义的行为。 charint默认参数促销之一。根据规范, 6.5.2.2函数调用,第6段:

  

对每个参数执行整数提升,并将类型为 float 的参数提升为 double

整数促销(来自 6.3.1.1布尔,字符和整数,第2段):

  

如果 int 可以表示原始类型的所有值(受宽度限制,对于位字段),该值将转换为 {{ 1}} ;否则,它会转换为 int 。这些被称为整数促销。所有其他类型都不会被整数促销更改。

答案 1 :(得分:2)

一步一步。 (A C回答)

  1. 'a'字符常量(C11 6.4.4.4 1)。 “整数字符常量的类型为int。” (§6.4.4.410)。将int分配给char 可能不适合,但该编译器知道常量的值并知道该值可表示为char。没有警告,没有问题。

    char c='a';
    
  2. 代码正在将char传递给具有...的函数,并且不会对参数进行原型化,因此应用“如果表示被调用函数的表达式具有不包含原型,对每个参数执行整数提升,...... §6.5.2.2 6cint的通常情况下被提升为CHAR_MAX <= INT_MAX。否则{{ 1}}被提升为c

    unsigned
  3. printf(some_format,c); 收到printf()int。给定格式说明符unsigned,代码需要"%d"。当int晋升为c时,所有行为都是定义良好的行为。

    int
  4. 在罕见的平台上,printf("%d",c); c提升为unsignedCHAR_MAX > INT_MAX的更深层部分适用:“...行为是undefined,除了以下情况: - 一个提升类型是有符号整数类型,另一个提升类型是相应的无符号整数类型,并且值可以在两种类型中表示; ...“。因此,如果§6.5.2.2 6可以表示为c,则没问题。否则,如果int的值不在c范围内,则使用int是UB。需要明确的是:"%d"甚至CHAR_MAX > INT_MAX的平台很少见,并且会带来额外的便携性问题。

  5. 使用UCHAR_MAX > INT_MAX并不是完美的格式。 char c; printf("%hhd",c);最适合作为角色类型。当需要窄类型的数值时,最好使用charsigned char

    IMO,以高度便携的方式打印unsigned char的数值:

    char

答案 2 :(得分:0)

  

但我想知道究竟发生了什么?

促销int。所以它基本上有效(&#34;有时可以工作&#34;,正如纯粹主义者所说)。

  

对于scanf是否相同?

scanf使用不同故事的变量地址。当scanf存储值时,由于变量大小不同,可能(通常会)发生内存损坏。