为什么类型转换从int打印浮动" 0.0000"

时间:2016-02-25 19:58:39

标签: c pointers casting sizeof

下面是我为了解类型转换而编写的一些代码,但我不明白为什么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;

}

3 个答案:

答案 0 :(得分:5)

首先,intfloat不是兼容类型。

在您的代码中,通过说

 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。