将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.
由于int
和float
具有不同的表示,因此没有理由相信这会起作用。
基本上你正在做的是你将一个void *
转换为float *
/ int *
,即你正在构建指针类型然后解除引用它们。 由于取消引用操作的行为取决于类型,因此没有理由认为这应该起作用。 您可以尝试此代码并查看差异:
int i = 10; void *p = &i; printf("%d\n", *(int*)(p));