以下程序的输出是什么以及为什么?
#include <stdio.h>
int main()
{
float a = 12.5;
printf("%d\n", a);
printf("%d\n", *(int *)&a);
return 0;
}
我的编译器打印0和1095237632.为什么?
答案 0 :(得分:7)
a
引用的内存包含处理器用来表示12.5的位模式。它是如何表示的:IEEE 754。它是什么样子的? See this calculator to find out: 0x4148000。解释为int时是什么? 1095237632.
为什么在不进行投射时会得到不同的值?我不是百分百肯定,但我猜这是因为编译器可以使用calling convention在不同于整数的位置传递浮点参数,所以当printf尝试在字符串后面找到第一个整数参数时,那里没有任何可预测的东西 (或者更可能的是,正如@Lindydancer指出的那样,浮点位可以在int的“右”位置传递,但是因为它们首先通过用零扩展来提升为双重表示,所以printf期望第一个为0 int为。)
答案 1 :(得分:7)
在这两种情况下,都会传递一个表示浮点值的位,并将它们打印为十进制。第二种情况是简单的情况,这里的输出与浮点数的基础表示相同。 (这假设调用约定指定float
的值与int
的传递方式相同,但不能保证。)
但是,在第一种情况下,当您将float
传递给printf
等vararg函数时,会将其提升为double
。这意味着传递的值将是64位,printf
将获取其中的一半(或者可能是垃圾)。在你的情况下,它显然已经获得了32个最低有效位,因为在float
到double
演员之后它们通常都是零。
为了使其绝对清楚,问题中的代码是而不是有效C,因为将值传递给printf
与格式说明符不匹配是非法的。
答案 2 :(得分:1)
这是因为floating point representation(参见IEEE 754标准)。
简而言之,一组位,当解释为整数时,在IEEE 755表示中产生12.5浮点值将给出奇怪的值,这与12.5值没有多大的共同点。
来自0
的{{1}} WRT,这是不正确的printf调用的内部未定义行为。