【问题标题】:Problems with scanf and doubles [duplicate]scanf和双打的问题[重复]
【发布时间】:2013-11-10 14:17:48
【问题描述】:

我无法理解为什么会发生这种情况: 使用以下代码;

    #include <stdio.h>

    int main() 
    {
        double x=123;

        printf("x is %f. Enter a new value for x.\n", x);
        scanf("%f", &x);
        printf("x is %f\n", x);

        return 0;
    }

当您输入 45678 作为 x 的新值时,将打印“x is 123.000017”。 我知道当你在扫描的时候使用 %lf 就可以解决这个问题,但是为什么在使用 %f 的时候会出现这种情况呢?

【问题讨论】:

    标签: c scanf


    【解决方案1】:

    我知道当你在扫描时使用 %lf 可以解决这个问题,但是为什么使用 %f 时会出现这种情况?

    printfscanf 函数参数之间的区别在于,您将值传递给 printf,而将值传递给 scanf,则传递指针(即值的地址)。根据 C 规则,当函数接受可变数量的参数时,所有参数都经过default promotions

    其中一项促销活动是将floats 转换为double,就像shorts 转换为int 一样。这就是为什么您可以将%f%lfprintf 一起使用:这两种类型的值都由编译器转换为double,因此访问它们是安全的。

    但是,指针没有这样的规则(并且有一个很好的理由:尝试将double 写入float 的空间将是未定义的行为)。这就是为什么在将参数传递给scanf 系列函数时必须区分%f%lf

    【讨论】:

    • +1 为default promotions提供了很好的解释
    【解决方案2】:
     scanf("%f", &x);
    

    应该是

     scanf("%lf", &x);
    

    printfscanf 之间的浮点转换说明符存在错误对称性。

    还要注意lf 转换说明符等价于printf 中的f 转换说明符(从c99 开始,之前未定义)。

    我知道当你在扫描时使用 %lf 可以解决这个问题,但是为什么使用 %f 时会出现这种情况?

    scanf 中的f 转换说明符需要指向float 的类型指针参数。通过将类型指针参数传递给double,您将调用未定义的行为。

    【讨论】:

      猜你喜欢
      • 2019-03-11
      • 2011-05-20
      • 1970-01-01
      • 2012-03-19
      • 2015-09-04
      • 2013-12-12
      • 2016-10-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多