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

时间:2013-10-23 04:58:07

标签: c

A

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,那么它的输出就是垃圾。

3 个答案:

答案 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.

由于intfloat有不同的表示形式,因此没有理由相信这会有效。

答案 2 :(得分:0)

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

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