将void指针转换为float * / int *时取消引用

一个

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  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 ,hex表示为,10。 c)浮动确实是41200000 。 根据IEEE 754 ,这意味着你有一个符号位,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. 

由于intfloat具有不同的表示,因此没有理由相信这会起作用。

基本上你正在做的是你将一个void *转换为float * / int * ,即你正在构建指针类型然后解除引用它们。 由于取消引用操作的行为取决于类型,因此没有理由认为这应该起作用。 您可以尝试此代码并查看差异:

 int i = 10; void *p = &i; printf("%d\n", *(int*)(p));