Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.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
将float*转换为char*、int*和char*不会产生预期结果_C_Pointers_Casting - Fatal编程技术网

将float*转换为char*、int*和char*不会产生预期结果

将float*转换为char*、int*和char*不会产生预期结果,c,pointers,casting,C,Pointers,Casting,据我所知,输出应该是3.14,3.14,3.14和256256,对吗?但这会产生不同的输出。有谁能告诉我为什么会这样 main() { float a = 3.14; int b = 256; char *p, *p1; p = (char *) &a; p1 = (char *) &b; printf("\nFLOAT:"); printf("\nValue of *p=%f",*p);

据我所知,输出应该是3.14,3.14,3.14和256256,对吗?但这会产生不同的输出。有谁能告诉我为什么会这样

    main()
    {
     float a = 3.14;
     int b = 256;
     char *p, *p1;
     p = (char *) &a;
     p1 = (char *) &b;
     printf("\nFLOAT:");
     printf("\nValue of *p=%f",*p);
     printf("\nValue of a=%f",a);
     printf("\nValue of *p=%f",*p);
     printf("\n\nINTEGER:");
     printf("\nValue of *p1=%d",*p1);
     printf("\nValue of b=%d",b);
     printf("\nValue of *p1=%d",*p1);
    }

    Output:
    FLOAT:
    Value of *p=0.000000
    Value of a=3.140000
    Value of *p=3.140001

    INTEGER:
    Value of *p1=0
    Value of b=256
    Value of *p1=0

表达式
*p
的类型为
char
。格式说明符
%f
需要类型为
float
的参数。将错误类型的参数传递给变量函数(如
printf
)会调用未定义的行为。

表达式
*p
的类型为
char
。格式说明符
%f
需要类型为
float
的参数。将错误类型的参数传递给变量函数(如
printf
)会调用未定义的行为。

由于float*和char*的大小不同,它的行为与预期不符。转换它们可能会牺牲您的表达准确性

由于float*和char*的大小不同,因此其行为与预期不符。转换它们可能会牺牲您的表达准确性

简单的回答是,当您使用
%f
格式说明符将
char
类型传递给
printf
时,您正在调用未定义的行为,因此您不应该期望有任何特别的结果

很长的答案取决于实现,但接下来是我对您的平台上可能发生的情况的观察。当您要求
printf
打印
double
值时(与
%f
格式说明符一样),它从堆栈中读取下一个
sizeof(double)
字节,并将其解释为浮点值并打印。在第一次
printf
调用中,第一次生成新的堆栈帧时,堆栈上实际传递的
char
后的数据等于零浮点值。在对
printf
的第二次调用中,生成了一个新的堆栈帧,可能覆盖了第一次调用所覆盖的相同空间。在这种情况下,会出现一个完整的
double
值,并按预期进行打印。当函数返回时,堆栈帧被“销毁”。为了提高效率,当函数返回且内容保持不变时,堆栈帧通常不会归零。在第三次调用
printf
时,再次传递一个字节,而要求
printf
sizeof(double)
字节解释为浮点值。上一次调用
printf
的堆栈帧现在包含上一次调用传递的
double
的值,其中一个字节被新参数的字节覆盖,从而打印出值

如果我将您的第二个
printf
呼叫更改为:

printf("\nValue of a=%f", 1.234);
第三次调用
printf
打印(在我的系统上):

这似乎验证了上述逻辑


总之,您要求
printf
从堆栈中读取的数据比实际传递给函数的数据多,因此,结果是未定义的。在您的情况下,读取的数据是以前调用的剩余数据,这解释了您在特定平台上得到的结果。(正如Ray指出的,参数的实际传递方式可能会有所不同,因为这取决于实现。有些系统会在寄存器中传递值,但点保持不变。)简而言之,当您使用
%f
格式说明符将
char
类型传递给
printf
时,您正在调用未定义的行为,因此您不应该期望有任何特殊情况

很长的答案取决于实现,但接下来是我对您的平台上可能发生的情况的观察。当您要求
printf
打印
double
值时(与
%f
格式说明符一样),它从堆栈中读取下一个
sizeof(double)
字节,并将其解释为浮点值并打印。在第一次
printf
调用中,第一次生成新的堆栈帧时,堆栈上实际传递的
char
后的数据等于零浮点值。在对
printf
的第二次调用中,生成了一个新的堆栈帧,可能覆盖了第一次调用所覆盖的相同空间。在这种情况下,会出现一个完整的
double
值,并按预期进行打印。当函数返回时,堆栈帧被“销毁”。为了提高效率,当函数返回且内容保持不变时,堆栈帧通常不会归零。在第三次调用
printf
时,再次传递一个字节,而要求
printf
sizeof(double)
字节解释为浮点值。上一次调用
printf
的堆栈帧现在包含上一次调用传递的
double
的值,其中一个字节被新参数的字节覆盖,从而打印出值

如果我将您的第二个
printf
呼叫更改为:

printf("\nValue of a=%f", 1.234);
第三次调用
printf
打印(在我的系统上):

这似乎验证了上述逻辑


总之,您要求
printf
从堆栈中读取的数据比实际传递给函数的数据多,因此,结果是未定义的。在您的情况下,读取的数据是以前调用的剩余数据,这解释了您在特定平台上得到的结果。(正如Ray指出的,参数的实际传递方式可能会有所不同,因为这取决于实现。一些系统会在寄存器中传递值,但点保持不变。)

我得到的答案与您的答案略有不同(http://ideone.com/RG4uq)这并不奇怪,因为混合浮点和积分类型的变量函数的行为是未定义的

下面是正在发生的事情。假设记忆
50000000  c3  f5  48  40   (a)
50000004  00  01  00  00   (b)
50000008  00  00  00  50   (p)
5000000c  04  00  00  50   (p1)