代码段的o / p:
printf("%f", 9/5);
在我的linux gcc 4.6.3(gcc myprog.c后跟./a.out)中:
-0.000000
:
2.168831
为什么会有差异?
我已经引用了这些链接:Why cast is needed in printf?和Implicit conversion in C?,但无法使用它。
有关键盘执行的信息: C:gcc 4.1.2 flags:-O -fmessage-length = 0 -fno-merge-constants -fstrict-aliasing -fstack-protector-all
编辑: 更多: 用于执行以下(在相同程序中)的键盘
printf("%f\n", 99/5);
printf("%f\n", 18/5);
printf("%f\n", 2/3);
printf("%f\n%f\n%f", 2, 3, 4);
printf("%f\n", 2);
o / p是
2.168831
2.168831
2.168831
0.000000
0.000000
-0.001246
-0.0018760.000000
前三个输出是相同的垃圾值(而不是最后一个)。想知道为什么。
答案 0 :(得分:4)
9/5被视为int
..当您使用格式说明符%f
(期望加倍)时会导致未定义的输出
打印正确的结果:
printf("%f", 9.0/5); // forces system to make sure that the argument is not treates as int
或
printf("%f\n",(double)9/5); // type casting the argument to a double .. this is more helpful
// in case you have a variable
我不确定codepad.org如何编译他们的代码..但对于gcc,你必须有正确的参数,使printf与格式说明符匹配
请仔细考虑以下内容:
#include <stdio.h>
int main(){
printf("%f %d %f\n",9/5,9/5,9.0/5);
printf("%f\n",1); // as suggested by devnull-again since the argument is not a double
// the output is undefined
return 0;
}
<强>输出:强>
$ ./test
0.000000 1 1.800000
0.000000
答案 1 :(得分:1)
这是未定义的行为,任何东西都可以打印出来。 9/5
的类型为int
。 %f
要求要传递double
(如果您传递float
,由于自动提升参数,它将转换为double
可变函数调用,所以也没关系。)
既然你没有给双,那么任何事情都可能发生。
在实践中,假设sizeof(int)==4
和sizeof(double)==8
,您的printf调用将读取4个字节的随机垃圾。如果那都是零,那么你将打印零。如果不是,你会打印随机的东西。
答案 2 :(得分:0)
键盘错误。 如果另有说明,每个数字都是int - 这是解决方案的关键。
在C / C ++中,9/5是int数,等于1 这就是你的原因:
printf("%f\n", 9 / 5);
与:
相同printf("%f\n", 1);
但是为什么它打印0.0你问 - 这就是原因。 当printf被赋予'%f'标志时,它会将参数视为float。
现在你的代码反汇编看起来像/可能看起来像那样:
printf("%f\n", 9 / 5);
push 1
call dword ptr [__imp__printf (0B3740Ch)]
push 1 在堆栈上移动(通常是32位0x1)
现在最重要的是32位值= 1(二进制):
(MSB)00000000 00000000 00000000 00000001(LSB)
如果将此模式视为32位浮点(根据this),则该模式意味着什么:
签名(位#31)= 0
exponent (接下来的8位,即#30 ..#23)all = 0
分数(其余位)包含1(dec)
理论上 但是指数= 0x0,这是特殊情况(读link)并被视为0.0 - 期间。