我尝试使用%d
打印浮动(我知道不应该这样做)。
但每次重新运行可执行文件时,它会给出不同的值)
我的问题是:为什么打印值每次都会改变?
我的系统:Ubuntu 14.04(64位)
编译:4.8.4
这是代码:
#include<stdio.h>
int main(){
float b = 12.3456;
printf("%d\n",b);
}
示例输出:
4bh1@mybox:~/C-fi$ ./test
-1629995944
4bh1@mybox:~/C-fi$ ./test
1147348376
4bh1@mybox:~/C-fi$ ./test
-1746005432
4bh1@mybox:~/C-fi$ ./test
510102216
4bh1@mybox:~/C-fi$
答案 0 :(得分:8)
使用printf
的错误格式说明符是undefined behavior的典型示例。这意味着行为是不可预测的,并且不能依赖于从一次运行到下一次运行的一致性。它可能会崩溃,它可能会打印随机值,或者它似乎可以正常工作。
实际发生的是有问题的编译器和体系结构的实现细节。但除非你真的在编写编译器,否则在挖掘它时没有多大用处。
如果您熟悉汇编程序,可以查看已编译的代码以查看它生成的指令。但请记住,不同的编译器(即使是具有不同优化设置的相同编译器)也很可能生成不同的汇编。
答案 1 :(得分:7)
可能通过FPU寄存器传递浮点值,但printf()
尝试从其他地方读取整数,它希望看到整数(堆栈或其他寄存器)。那个地方的内容没有具体说明。严格说(正如@dbush所提到的)你的代码会导致未定义的行为。
答案 2 :(得分:1)
如评论中所示,这听起来像是未定义的行为,它解释了(好吧,某种程度上)正在发生的事情。
如果你想阅读一个浮点数的内部表示,或者你想对数字做一些低级别的黑客攻击,那么这样做的方法很简单,例如:
union {
float f;
int i;
} n;
n.f = 12.3456;
printf("%d\n", n.i); // should be the same number each time
请注意,这只适用于float
和int
在您的系统上具有相同尺寸的情况,但应适用于大多数人。如果您想确定,可以添加assert(sizeof(float) == sizeof(int))
。