意外的输出打印一个浮动转换为int

时间:2011-07-04 16:48:18

标签: c pointers

#include <stdio.h>
int main()
{
    float a = 12.5;

    printf("%d\n", a);
    printf("%d\n", *(int *)&a);

    return 0;
}

此外,您如何解释表达式*(int *)&a

5 个答案:

答案 0 :(得分:6)

它接受float的地址,将其转换为整数指针,然后将其解引用为整数。完全错了。

这里至少有两件事是错的:

  • 没有人说int和float的指针需要大小相同
  • float的表示看起来与signed int
  • 的表示形式完全不同

因此输出到第二个printf(如果它没有发生崩溃,因为它是未定义的行为,按照第一点)可能会有一些奇怪的,巨大的数字。

答案 1 :(得分:3)

此代码的作者试图获取float的位并将它们重新解释为int,但*(int *)&a调用未定义的行为,而现代编译器可能不会执行代码作者的意图。将错误类型的参数传递给printf更糟糕的是未定义的行为;在x86_64这样的现代拱门上肯定无法正常工作。相反,你可以使用:

#include <stdio.h>
int main()
{
  float a = 12.5;
  int b;
  memcpy(&b, &a, sizeof b);
  printf("%d\n", b);
  return 0;
}

以获得理想的效果。

答案 2 :(得分:1)

我的编译器对此进行标记并发出严厉警告。

$ make foolish
cc     foolish.c   -o foolish
foolish.c: In function ‘main’:
foolish.c:5: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘double’
$ ./foolish
1606416928
1095237632
$ 

想要这样做的原因是什么?

答案 3 :(得分:0)

如果您创建该行printf("%08X\n", *(unsigned int *)&a);,则它会打印浮点数的二进制表示。 See here了解详情。

答案 4 :(得分:0)

size(float)和sizeof(double)的大小往往是sizeof(short)的一些倍数,并且通常是sizeof(int)(为了满足不同的需要,甚至IEEE浮点标准也允许多个浮点格式)。

假设前面提到的未定义指针行为不会终止程序,在大多数环境中,这只会占用其中一个int的位并将其单独打印出来。浮点数的内部确保这与原始浮点值有很大不同。

printf( "%d sizeof(short)\n", int(sizeof(short)) );
printf( "%d sizeof(int)\n", int(sizeof(int)) );
printf( "%d sizeof(float)\n", int(sizeof(float)) );
printf( "%d sizeof(double)\n", int(sizeof(double)) );
printf( "%d sizeof(long double)\n", int(sizeof(long double)) );