面试问题打印浮点数

use*_*er7 2 c floating-point printf

以下程序的输出是什么?为什么?

  #include <stdio.h>
  int main()
  {
   float a = 12.5;
   printf("%d\n", a);
   printf("%d\n", *(int *)&a);
   return 0;
  }
Run Code Online (Sandbox Code Playgroud)

我的编译器打印0和1095237632.为什么?

ASh*_*lly 7

所引用的存储器a保持处理器用来表示12.5的位模式.它是如何代表的: IEEE 754.它是什么样子的? 请参阅此计算器以查找:0x4148000.解释为int时是什么?1095237632.

为什么在不进行投射时会得到不同的值?我不是百分百肯定,但我猜它是因为编译器可以使用一个调用约定,它将浮点数参数传递到与整数不同的位置,所以当printf尝试在字符串后面找到第一个整数参数时,没有任何可预测的那里.
(或者更可能的是,正如@Lindydancer指出的那样,浮点位可以在int的"右"位置传递,但是因为它们首先通过用零扩展来提升为双重表示,所以printf期望第一个为0 int是.)


Lin*_*cer 7

在这两种情况下,您都传递一个表示浮点值的位,并将它们打印为十进制.第二种情况是简单的情况,这里的输出与浮点数的基础表示相同.(这假定调用约定指定a的值以与a float相同的方式传递int,这是不可保证的.)

但是,在第一种情况下,当你传递float给一个vararg函数时,就像printf它被提升为一个double.这意味着传递的值将是64位,并且printf将获取其中的一半(或者可能是垃圾).在你的情况下,它显然已经拿起了至少32位显著,因为它们通常会后的所有零floatdouble投.

为了使其绝对清楚,问题中的代码不是有效的C,因为传递值printf与格式说明符不匹配是非法的.