下面是我为了解类型转换而编写的一些代码,但我不明白为什么float或double的值被打印为" 0.000000"即使我从整数数组中键入cast或尝试从联合的地址解释。
#include <stdio.h>
union test1
{
int x;
float y;
double z;
};
int main()
{
int x[2]={200,300};
float *f;
f=(float*)(x);
printf("%f\n",*f); /*(1)why is this value 0.0*/
*f=(float)(x[0]); /*(2)this works as expected and prints 200.00000*/
printf("%f\n",*f);
union test1 u;
u.x=200;
/*(3)this line give compilation error why*/
//printf ("sizeof(test1) = %d \n", sizeof(test1));
/*(4) this line also prints the value of float and double as 0.0000 why*/
printf ("sizeof(test1) = %lu u.x:%d u.y:%f u.z:%lf \n", sizeof(u), u.x, u.y, u.z);
return 0;
}
答案 0 :(得分:5)
首先,int
和float
不是兼容类型。
在您的代码中,通过说
f=(float*)(x);
你打破strict aliasing rule。任何进一步的用法都会调用undefined behavior。
简单来说,您不能只是指向float
的指针,将其转换为int *
并取消引用int *
以获得int
值。引用wikipedia article,
函数中的[..]指针参数如果指向根本不同的类型,则假定它们不是别名,[...]
有关详细说明,请参阅已经链接的常见问题解答答案。
答案 1 :(得分:3)
printf("%f\n",*f); /*(1)why is this value 0.0*/
您正在使用int
的地址并将其视为包含float
的地址。这是未定义的行为。
答案 2 :(得分:0)
printf("%f\n",*f); /*(1)why is this value 0.0*/
这实际上是未定义的行为,但是这并不能解释为什么在你的情况下你有0.0。结果可能是任何东西,因为它是未定义的行为,但是对于给定的编译器和给定的机器,行为虽然没有指定,但产生了一些东西。
您正在以浮点数形式读取包含int编码的内存; 200作为int的编码很可能被读作一个非常小的值(一个非规范化的小浮点数)作为一个浮点并写为0.0。在我的机器上,非规范化浮点数用printf打印为0.0(不知道它是否是标准的printf行为)。
对于浮点编码,请阅读IEEE 754。