C 浮点数每次执行都会改变 %d 个值

C Floating point changes %d value every time executed

我尝试使用 %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$ 

可能浮点值是通过 FPU 寄存器传递的,但是 printf() 试图从其他地方读取整数,它希望看到整数(堆栈或另一个寄存器)。那个地方的内容是未指定的。严格来说(正如@dbush 所提到的)您的代码会导致未定义的行为。

printf 使用错误的格式说明符是 undefined behavior 的典型示例。这意味着行为是不可预测的,不能依赖于一个 运行 下一个行为是一致的。它可能会崩溃,它可能会打印随机值,或者它可能看起来正常工作。

实际发生的是所讨论的编译器和体系结构的实现细节。但是除非你真的在写一个编译器,否则深入研究它没有多大用处。

如果您熟悉汇编程序,您可以查看编译后的代码以了解它生成了哪些指令。但是请记住,不同的编译器(即使是具有不同优化设置的相同编译器)很可能会生成不同的程序集。

正如评论中所指出的,这听起来像是 未定义的行为,它解释了(嗯,有点)正在发生的事情。

如果您想读取浮点数的内部表示,或者您想对数字进行一些低级修改,可以使用简单的方法,例如:

union {
    float f;
    int i;
} n;

n.f = 12.3456;
printf("%d\n", n.i); // should be the same number each time

请注意,这仅适用于 floatint 在您的系统上具有相同大小的情况,但 应该 大多数人都是这种情况。如果您想确定,可以添加 assert(sizeof(float) == sizeof(int))