一个
int i = 10;
void *p = &i;
printf("%f\n", *(float*)p);
乙
float i=10.00;
void *p = &i; // no change
printf("%d\n", *(int*)p);
为什么 A 打印 0.0,而不是 10.0?如果我们将 A 更改为 B,那么它的输出就是垃圾。
int i = 10;
void *p = &i;
printf("%f\n", *(float*)p);
float i=10.00;
void *p = &i; // no change
printf("%d\n", *(int*)p);
为什么 A 打印 0.0,而不是 10.0?如果我们将 A 更改为 B,那么它的输出就是垃圾。
为了更准确地了解其他人所说的话,这里有一个测试:
#include <stdlib.h>
int main()
{
int a = 10;
float b = 10;
char * p;
p = &a;
printf("int repr: %02x %02x %02x %02x\n", p[0], p[1], p[2], p[3]);
p = &b;
printf("float repr: %02x %02x %02x %02x\n", p[0], p[1], p[2], p[3]);
return 0;
}
输出是
int repr: 0a 00 00 00
float repr: 00 00 20 41
由此可见:
a) 它是一个小端机器,因为 int 的最低字节首先出现在内存中 b) int 具有字节表示0a 00 00 00
,所以值是0000000a
,10 的十六进制表示。 c) 浮点数是确实41200000
。根据IEEE 754,这意味着您有 1 个符号位、8 个指数位和 23 个尾数位。符号为 0 (+),指数为0x82
,表示 +3,尾数为010000...
,表示二进制的 1.01 或十进制的 1.25。
这些数据一起形成了 2*2*2*1.25 = 8*1.25 = 10 的值。
因为在第一种情况下您并没有真正进行强制转换——您正在强制转换指针类型。
如果你想要 10.0,你可以这样做:
int i = 10;
printf("%f\n", (float)i);
这是你现在正在做的事情:
int i = 10; // Create int i and initialize to 10.
void *p = &i; // Get an untyped pointer and set it to the address of i
printf("%f\n", *(float*)p); // Treat the pointer p as a float pointer and dereference it, printing it as a float.
由于int
并且float
有不同的表示,没有理由相信这会奏效。
基本上,您正在做的是将 avoid *
转换为float *
/ int *
,即,您正在转换指针类型,然后取消引用它们。由于取消引用操作的行为因类型而异,因此没有理由相信这应该有效。你可以试试这段代码,看看有什么不同:
int i = 10;
void *p = &i;
printf("%d\n", *(int*)(p));