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,那么它的输出就是垃圾。
答案 0 :(得分:5)
为了更准确地了解其他人所说的,这是一个测试:
#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
。根据{{3}},这意味着你有一个符号位,8位指数和23位尾数。符号为0(+),指数为0x82
,表示为+3,尾数为010000...
,表示二进制为1.01,十进制为1.25。
这些数据一起形成值2 * 2 * 2 * 1.25 = 8 * 1.25 = 10.
答案 1 :(得分:4)
因为在第一种情况下你并没有真正进行强制转换 - 你正在构建指针类型。
如果您想要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
有不同的表示形式,因此没有理由相信这会有效。
答案 2 :(得分:0)
基本上你正在做的是将void *
转换为float *
/ int *
,即你正在构建指针类型然后取消引用它们。由于取消引用操作的行为取决于类型,因此没有理由认为这应该起作用。您可以尝试使用此代码并查看其中的差异:
int i = 10;
void *p = &i;
printf("%d\n", *(int*)(p));