【问题标题】:Use of %d inside printf to print float value gives unexpected output在 printf 中使用 %d 打印浮点值会产生意外的输出
【发布时间】:2017-03-19 22:37:14
【问题描述】:
#include<iostream>
#include<stdio.h.>
using namespace std;
int main()
{
    float f=11.11;
    printf("%d",f);
}

当我在 dev c++ 中执行以下代码时,它会给出输出 -536870912。 当我在在线教程点编译器上执行相同的代码时,每次运行都会有所不同。背后的原因可能是什么?

【问题讨论】:

  • 注意:您使用的是 C++ 编译器,而不是 C 编译器。

标签: c types casting int


【解决方案1】:

这里的转换说明符和变量的类型不匹配:

  printf("%d",f);

传递给printf 其他参数然后由格式字符串给出的转换说明符指定会引发未定义的行为。从那一刻起,一切都可能发生。

要解决此问题,请使用正确的转换说明符。

对于浮点变量,使用转换说明符f,它需要double。但是,当 float 传递给像 printf 这样的可变参数函数时,float 会提升为 double

【讨论】:

    【解决方案2】:

    我不确定你是问为什么不打印 11? 还是 为什么它在不同的编译器下打印出不同的答案?

    它没有打印 11 的原因是,正如其他答案所解释的那样,%d 不打印浮点数,并且在printf 调用中没有自动转换来修复传递和预期类型之间的不匹配。

    它在不同的编译器下打印不同的东西的原因是它是未定义的行为,这意味着任何事情都可能发生。假设你走到你的车前,松开前轮上的所有螺母直到它即将脱落,然后上车,然后在路上高速行驶直到车轮确实脱落,然后你失去控制并坠入沟渠。假设你买了一辆新车,明天做同样的事情,只是你碰巧撞到了一棵树上。此时,您可以采取两种方法:

    1. 试着弄清楚是什么微妙的因素导致你有一天撞到沟里,另一天撞到树上。为什么不能更重复?
    2. 决心不再尝试这种愚蠢的实验。

    【讨论】:

    • @harishbisht29 因为%c定义为接受int。还因为当您调用printf 时,参数确实会发生一些自动转换:charshort 被提升为intfloat 被提升为double。这些被称为通常的参数提升或类似的东西,它们适用于任何接受可变数量参数的函数(如printf),因此没有固定的原型。
    【解决方案3】:

    如果参数与格式说明符不匹配,则为undefined behaviour。使用 %f 打印浮点数。

    printf("%f",f);
    

    您应该能够使用良好的编译器轻松捕获此类错误。 GCC 产生:

    warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘double’ [-Wformat=]
    

    为您的代码。

    P.S.:您的 stdio.h 标头包含中有一个杂散点。

    【讨论】:

    • f 实际上至少自 C99 以来期望 double 而不是 float
    • 确实,但 printf 会自动提升为 double
    【解决方案4】:

    这是一个浮点数,使用

    printf("%f" , f); 
    

    如果你不这样做,这是一个未定义的行为。 要理解,您可以尝试将值为 -1 的 int 转换为 unsigned int。

    您将获得巨大的价值。

    【讨论】:

    • f 实际上至少自 C99 以来期望 double 而不是 float
    • @alk 因为对于可变参数参数小于double 的值和变量被提升为double,所以这并不重要。
    • 虽然它可能会产生意外的行为,但将负符号整数转换为无符号整数并不是 UB。
    猜你喜欢
    • 2021-04-04
    • 2013-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-20
    相关资源
    最近更新 更多