我知道这是错误的,gcc会给你一个警告,但为什么它会起作用(即数字打印正确,有一些舍入差异)?
int main() {
float *f = (float*) malloc(sizeof(float));
*f = 123.456;
printf("%f\n", *f);
printf("%f\n", f);
return 0;
}
修改 是的,我正在使用带有32位机器的gcc。我很想知道其他编译器会得到什么结果。
在克里斯托夫的建议之后,我更多地干涉了一些事情:
int main() {
float *f = (float*) malloc(sizeof(float));
*f = 123.456;
printf("%f\n", f); // this
printf("%f\n", *f);
printf("%f\n", f); // that
return 0;
}
这导致第一次printf打印的值与上一次printf不同,尽管是相同的。
答案 0 :(得分:11)
对printf()
语句重新排序,你会发现它不再有效,所以GCC肯定不会修复你背后的任何内容。
至于它为什么会起作用:由于变量参数的默认参数提升,你实际上会在第一次调用时传递double
。由于系统上的指针似乎是32位,第二次调用只会覆盖64位浮点值的下半部分。
关于修改后的例子:
f
*f
提升为双精度(double)*f
(因为这些位仍然保留在最后一次调用的堆栈中);与第一种情况一样,低位将再次来自指针f
答案 1 :(得分:1)
我的打印数字不正确。
<强>输出:强>
123.456001
0.000000
我正在使用VC ++ 2009。
答案 2 :(得分:1)
printf
不了解实际参数类型。它只是分析格式字符串并相应地解释堆栈上的数据。
巧合(或多或少=))指向float的指针与平台上的float(32位)具有相同的大小,因此在从中删除此参数后,堆栈是平衡的。
在其他平台或其他数据类型上,这可能无效。