C Printf中的类型转换
代码段的o/p:C Printf中的类型转换,c,gcc,type-conversion,printf,C,Gcc,Type Conversion,Printf,代码段的o/p: printf("%f", 9/5); 在我的linux gcc 4.6.3(gcc myprog.c后跟./a.out)中: -百万 在codepad.org中: 2.168831 为什么不同 我已经参考了链接:和,但没能利用它 有关代码板执行的信息: C:gcc 4.1.2 标志:-O-fmessage length=0-fno合并常量-fstrict别名-fstack protector all 编辑: 更多: 用于在(同一程序中)代码板中执行以下操作 o/p为 2.16
printf("%f", 9/5);
2.168831
2.168831
2.168831
0.000000
0.000000
-0.001246
-0.0018760.000000
前三个输出是相同的垃圾值(而不是最后一个)。想知道为什么。9/5被视为
int
。。当您使用格式说明符%f
时,这会导致未定义的输出(需要双精度)
要打印正确的结果,请执行以下操作:
printf("%f", 9.0/5); // forces system to make sure that the argument is not treates as int
或
我不知道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
9/5被视为
int
。。当您使用格式说明符%f
时,这会导致未定义的输出(需要双精度)
要打印正确的结果,请执行以下操作:
printf("%f", 9.0/5); // forces system to make sure that the argument is not treates as int
或
我不知道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
这是未定义的行为,任何东西都可以打印出来<代码>9/5的类型为
int
%f
需要传递一个double
(如果传递一个float
,由于变量函数调用的参数自动升级,它将转换为double
,所以也可以)
既然你不给替身,任何事情都有可能发生
实际上,假设
sizeof(int)==4
和sizeof(double)==8
,printf调用将读取4字节的随机垃圾。如果都是零,那么就打印零。如果不是,您将打印随机内容。这是未定义的行为,任何内容都可以打印<代码>9/5的类型为int
%f
需要传递一个double
(如果传递一个float
,由于变量函数调用的参数自动升级,它将转换为double
,所以也可以)
既然你不给替身,任何事情都有可能发生
实际上,假设
sizeof(int)==4
和sizeof(double)==8
,printf调用将读取4字节的随机垃圾。如果都是零,那么就打印零。否则,您将随机打印内容。代码板错误。
如果另外说明,每个数字都是int-这是解决问题的关键
在C/C++中,9/5是整数,等于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)]
推送1在堆栈上移动(通常为32位0x1)
现在最重要的是32位值=1的外观(二进制):
(MSB)00000000000000000000000000000001(LSB)
如果将此模式视为32位浮点(根据):
符号(位31)=0
指数(下一个8位即30..23)全部也=0
分数(剩余位)包含1(十进制)
理论上这是,但指数=0x0,这是一种特殊情况(读取),被视为0.0-周期。码本是错误的。
如果另外说明,每个数字都是int-这是解决问题的关键
在C/C++中,9/5是整数,等于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)]
推送1在堆栈上移动(通常为32位0x1)
现在最重要的是32位值=1的外观(二进制):
(MSB)00000000000000000000000000000001(LSB)
如果将此模式视为32位浮点(根据):
符号(位31)=0
指数(下一个8位即30..23)全部也=0
分数(剩余位)包含1(十进制)
理论上这是,但指数=0x0,这是一种特殊情况(读取),被视为0.0-句点。您可以通过修改示例使答案更加完整,以包含以下结果:
printf(“%f\n”,1)代码>谢谢你提供的信息。。我还添加了有关codepad编译方式的详细信息。@Karthiprime非常欢迎您……如果他们帮助您,请接受答案。您可以通过修改示例使答案更加完整,包括以下结果:printf(“%f\n”,1)代码>谢谢你提供的信息。。我还添加了有关codepad编译的详细信息。@Karthiprime非常欢迎您……如果他们帮助您,请接受回答。使用反汇编的解释非常有用@Mat有附加信息。代码板没有错误。当参数的类型与其格式说明符不匹配时,C标准不定义行为。期望int
参数的字节将被解释为float
或double
是不正确的。IMHO它是完全正确的-%f”格式说明符用于printf让它知道应该如何处理堆栈上的值(如果使用cdecl)。Printf只是不知道堆栈上有什么-它必须信任用户。如果用户说“%f”,那么printf除了从堆栈中提取4个字节并将它们解释为float之外,就没有别的办法了。如果它不能int