【问题标题】:Unexpected results when using printf使用 printf 时出现意外结果
【发布时间】:2013-11-07 04:11:01
【问题描述】:

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

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,但在第二种情况下不是。为什么我会看到这些不同的结果?

【问题讨论】:

  • 您应该启用警告才能理解。在第一种情况下是format ‘%d’ expects type ‘int’, but argument 2 has type ‘double’ 在第二种情况下是conversion to ‘int’ from ‘double’ may alter its value。我想警告很好地解释了自己。

标签: c type-conversion printf undefined-behavior


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    %d 格式说明符告诉 printf 你正在传递一个 int 但在第一种情况下你正在传递一个 double 这也是 @987654321 @ 等结果不可靠。结果:

    money+money*0.4
    

    double,因为 浮动常量double,除非它具有诸如 f 之类的后缀以及 的结果乘法加法也是double,因为这两种操作都需要进行通常的算术转换,这将导致值的money 被转换为 double 用于操作。

    在第二种情况下,您正确地传递了 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) 如果任何参数不是相应转换规范的正确类型,则行为未定义。

    【讨论】:

      【解决方案3】:

      检查第 7 行中的乘法。

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-10-04
        • 2021-02-07
        • 1970-01-01
        • 2020-10-20
        • 1970-01-01
        • 2017-07-29
        • 1970-01-01
        • 2018-07-18
        相关资源
        最近更新 更多