奇怪的结果将指针打印为C中的浮点
我知道这是错误的,gcc会给你一个警告,但为什么它会工作,即数字打印正确,有一些舍入差异奇怪的结果将指针打印为C中的浮点,c,pointers,gcc,floating-point,printf,C,Pointers,Gcc,Floating Point,Printf,我知道这是错误的,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
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不同,尽管它们相同。我没有正确打印数字 输出:
我正在使用VC++2009。我没有正确打印数字 输出: 我正在使用VC++2009。printf不知道实际的参数类型。它只是分析格式字符串并相应地解释堆栈上的数据 巧合的是,指向float的指针的大小与平台上的float 32位相同,所以从堆栈中删除此参数后,堆栈是平衡的 在其他平台或其他数据类型上,这可能不起作用。printf不知道实际的参数类型。它只是分析格式字符串并相应地解释堆栈上的数据 巧合的是,指向float的指针的大小与平台上的float 32位相同,所以从堆栈中删除此参数后,堆栈是平衡的 在其他平台或其他数据类型上,这可能不起作用。重新排序printf语句,您将看到它不再起作用,因此GCC肯定不会在背后修复任何东西 至于它工作的原因:由于变量参数的默认参数提升,第一次调用实际上会传递一个double。由于系统上的指针似乎是32位的,第二次调用只覆盖64位浮点值的下半部分 关于您修改的示例: 第一个调用将打印一个双精度值,其中较高的32位是垃圾,而指针f的位值较低 第二个调用打印提升为双精度的*f值 第三次调用打印一个双精度值,其中较高的32位来自double*f,因为这些位仍然保留在上一次调用的堆栈上;与第一种情况一样,低位将再次来自指针f 重新排序printf语句,您将看到它将不再工作,因此GCC肯定不会在背后修复任何东西 至于它工作的原因:由于变量参数的默认参数提升,第一次调用实际上会传递一个double。由于系统上的指针似乎是32位的,第二次调用只覆盖64位浮点值的下半部分 关于您修改的示例: 第一个调用将打印一个双精度值,其中较高的32位是垃圾,而指针f的位值较低 第二个调用打印提升为双精度的*f值 第三次调用打印一个双精度值,其中较高的32位来自double*f,因为这些位仍然保留在上一次调用的堆栈上;与第一种情况一样,低位将再次来自指针f
几乎正确:参数是按值传递的,但将指针推到堆栈只会覆盖提升的64位浮点值的下半部分。您应该发布实际得到的输出。你是说第二个printf实际上是在打印“123”之类的东西吗?几乎正确:参数是按值传递的,但将指针推到堆栈只会覆盖提升的64位浮点值的下半部分。你应该发布实际得到的输出。你是说第二个printf实际上是在打印“123”之类的东西吗?
123.456001
0.000000