Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
奇怪的结果将指针打印为C中的浮点_C_Pointers_Gcc_Floating Point_Printf - Fatal编程技术网

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

奇怪的结果将指针打印为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

我知道这是错误的,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不同,尽管它们相同。

我没有正确打印数字

输出:


我正在使用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