printf()函数的异常行为是什么?

5

可能是重复问题:
使用%f打印整数变量

该问题可能与已有的问题重复:如何使用%f格式化字符串来打印整数变量。请参考上述链接。
#include<stdio.h>

int main()
{
    printf("%f",9/5);
    return 0;   
}

输出:0.000000

有人能解释一下上面程序的输出吗?

程序的输出不应该是1.000000吗?


1
启用编译器警告,您应该会收到通知,printf参数类型与格式字符串不匹配。 - Kos
如果您想要输出1.000000,那么请使用(float)(9/5)。似乎没有任何答案提到这一点的原因。 - Kos
@pb2q:这并不是那个问题的重复。这个问题有两个问题:int除法产生int,并将结果传递给带有"%f"printf。我不确定我是否见过具有该组合的问题。 - Keith Thompson
2
OP仍然知道int除法,但如果它不被认为是问题的一部分,那么它会增加一个不必要的层。 - chris
1
@Kos:gcc会给出警告,其他编译器呢?而且你最好转换为“double”,因为它无论如何都会被提升。 - Keith Thompson
@chris:说得好(我刚回来这里提到)。投票关闭为重复。 - Keith Thompson
6个回答

5
printf("%f",9/5);

这个声明是未定义行为,因为参数必须为double类型,而9/5是int类型。使用9/5.0以获得double类型的参数(并且正确的浮点数除法)。

4

9/5 是一个 int 类型。如果你使用 "%f" 格式符将 int 参数传递给 printf 函数,那么行为是未定义的。

如果你想要得到 1.800000,请尝试使用 9.0/5.0;如果你想要得到 1.000000,请使用 (double)(9/5)


3
为什么会这样呢? 因为 9 / 5 是通过将两个整数相除得到的,相除结果是一个整数值1。但是,由于这是 int 类型,而指定的 %f 格式需要一个浮点数,因此这是未定义的行为。 附注:你可能需要
9.0 / 5

或者

9 / 5.0

或者

9.0 / 5.0

1
崩溃其实是一件好事;它会让问题变得更加明显。 - Keith Thompson
@KeithThompson,你真的因为这个给了我一个负一分吗? - user529758
不是我。那只是对你的答案的评论,而不是对你的评论的回应。 - Keith Thompson
@KeithThompson 哦,好的。我会编辑我的答案。 - user529758

2

回复:程序的输出应该是1.000000吗?

如果您的除法结果是浮点值而不是int,那么输出确实会是1.000000。由于您尝试使用%f格式说明符打印一个int,所以结果是未定义行为。

更多细节:

有两个相关的问题:

  1. 您从除法中得到一个整数结果,但尝试使用%f格式说明符格式化浮点值

  2. (您的问题似乎暗示您已经意识到这一点) 整数除法会产生一个整数,这就是为什么%f格式说明符不适用的原因。当格式说明符和参数不匹配时,行为是未定义的。

    为了避免整数结果,请尝试:

    9.0 / 59 / 5.0 或甚至 9.0 / 5.0

    以获得您期望的结果,然后使用%f格式说明符即可按预期运行。

    请注意,在进行整数除法时,结果将是另一个整数。但是,如果至少有一个操作数是浮点数,则另一个操作数也会被提升为浮点数,并且除法将产生浮点值。

    使用整数除法会得到截断,这意味着结果的小数部分被舍去。


如果这是整数除法的例子,输出应该为1.0,但实际输出为0.0。这是因为%f格式需要一个double类型的值,而提供的是int类型的值。 - Femaref
@Femaref 同意,我正在调整我的答案,就在你发表评论的时候 :) .. 谢谢。 - Levon

0

这是因为9/5的结果是1,是整数类型。小数部分被简单地截断了。要实现您想要的效果,请强制使用浮点运算进行除法运算,例如5.0/95/9.05.0/9.0(float) 5/9

当整数参数的类型与%f绑定时,行为是未定义的。

这在C99标准第7.21.6.1节第9段中说明。该段引用如下:

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


1
不,输出是0.0,而不是1.0。那是因为他试图用%f作为格式显示一个整数。 - Femaref

0

答案很简单。 9是整数,5也是整数。当整数被整数除时,结果将为0,并且它将升级为0.00000,因为您在printf()中使用了“%f”。 如果您想要正确的结果,请执行 9.0/5 现在你一定会得到正确的答案


这句话怎么跟20分钟前发布的回答有什么新意呢? - Levon
1
@Levon 答案很简单:因为在 SO 上打字的速度比光速还快,新用户无法跟上,很明显他们在意识到有人已经回答之前就会回答。 ;) - pankar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接