使用printf时出现意外结果

时间:2013-10-28 11:42:57

标签: c type-conversion printf undefined-behavior

我看到两个程序的结果不同,我期望产生相同的输出,第一种情况:

int money;

printf("Enter the price of the car: ");
scanf("%d", &money);

printf("\nResult: %d .\n", money+money*0.4);

第二种情况:

int money;

printf("Enter the price of the car: ");
scanf("%d", &money);

money=money+money*0.4;

printf("\nResult: %d .\n", money );
return 0;

在第一种情况下,printf的结果为0,但在第二种情况下则不然。为什么我会看到这些不同的结果?

3 个答案:

答案 0 :(得分:7)

%d格式说明符告诉printf您正在传递 int ,但在第一种情况下,您传入的是 double 也是undefined behavior因此结果不可靠。结果:

money+money*0.4

double ,因为浮动常量 double ,除非它有f等后缀和<的结果< em>乘法和加法也是 double ,因为通常的算术转换这两个操作都受到影响,哪些会导致要为操作转换为 double money值。

在第二种情况下,您正确地传入 int ,因为您要将结果分配给money

money=money+money*0.4

它将截断 double 值。我不确定您使用的编译器,但clanggcc没有任何警告标志都警告不正确的格式说明符,gcc例如说:

  

警告:格式'%d'需要类型为'int'的参数,但参数2的类型为'double'[-Wformat]

因此,如果您没有看到该行的任何警告,您应该考虑将警告级别设置得更高。

为了完整起见,draft C99 standard部分7.19.6.1 fprintf函数,其中还包含printf格式说明符,在段落 9中说:

  

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

答案 1 :(得分:3)

检查第7行的乘法。

您可以将最后一行更改为:

float price = money * 1.4;
printf( "\nResult %f.\n", price);

答案 2 :(得分:1)

money+money*0.4会隐式地将money强制转换为double,从而使%d成为该值的错误格式说明符。