#include <stdio.h>
int main()
{
float a = 12.5;
printf("%d\n", a);
printf("%d\n", *(int *)&a);
return 0;
}
此外,您如何解释表达式*(int *)&a
?
答案 0 :(得分:6)
它接受float的地址,将其转换为整数指针,然后将其解引用为整数。完全错了。
这里至少有两件事是错的:
因此输出到第二个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)) );