奇怪的结果将指针打印为C中的float

Ask*_*ker 1 c floating-point printf gcc pointers

我知道这是错的,gcc会给你一个关于它的警告,但为什么它会起作用(即数字打印正确,有一些舍入差异)?

int main() {
   float *f = (float*) malloc(sizeof(float));
   *f = 123.456;
   printf("%f\n", *f);
   printf("%f\n", f);
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

编辑: 是的,我正在使用带有32位机器的gcc.我很想知道其他编译器会得到什么结果.

在Christoph的建议之后,我更多地干涉了一些事情:

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;
}
Run Code Online (Sandbox Code Playgroud)

这导致第一次printf打印的值与最后的printf不同,尽管是相同的.

Chr*_*oph 11

重新排序这些printf()语句,你会发现它不再适用,所以GCC肯定不会修复你背后的任何内容.

至于它为什么会起作用:由于变量参数的默认参数提升,你实际上会double在第一次调用时传递一个.由于系统上的指针似乎是32位,第二次调用只会覆盖64位浮点值的下半部分.

关于您的修改示例:

  • 第一个调用将打印一个双精度值,其中较高的32位是垃圾,指针的位值越低 f
  • 第二个调用打印*f提升为double精度的值
  • 第三个调用打印一个双精度值,其中较高的32位来自(double)*f(因为这些位仍然保留在最后一次调用的堆栈中); 与第一种情况一样,低位将再次来自指针f