2

一个

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

4

3 回答 3

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。根据IEEE 754,这意味着您有 1 个符号位、8 个指数位和 23 个尾数位。符号为 0 (+),指数为0x82,表示 +3,尾数为010000...,表示二进制的 1.01 或十进制的 1.25。

这些数据一起形成了 2*2*2*1.25 = 8*1.25 = 10 的值。

于 2013-10-23T05:42:45.027 回答
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有不同的表示,没有理由相信这会奏效。

于 2013-10-23T05:03:39.320 回答
0

基本上,您正在做的是将 avoid *转换为float */ int *,即,您正在转换指针类型,然后取消引用它们。由于取消引用操作的行为因类型而异,因此没有理由相信这应该有效。你可以试试这段代码,看看有什么不同:

int i = 10;
void *p = &i;
printf("%d\n", *(int*)(p));
于 2013-10-23T05:25:42.403 回答