0

我试图理解为什么以下代码不起作用......请帮助:

void incme(double *p)
{
    printf("%x,%x\n",p,*p);
    *p = *p + 1;
    printf("%x,%x\n",p,*p);
}
int main()
{
    int i = 1;
    incme((double *)&i);    
    printf("%x,%x",&i,i);
}

输出是:

ff99a348,1
ff99a348,1
ff99a348,1

我期待: ff99a348,1 ff99a348,2 ff99a348,2
它打破了我对指针的了解......

谢谢。

编辑:

我要问的主要问题是 incme((double *)&i); 为什么不将其转换为加倍并将其传递给函数?...抱歉没有指出eailer ....

4

3 回答 3

3

因为未定义的行为。整数不是浮点数,浮点数也不是整数。除此之外,我想你会发现sizeof(int) != sizeof(double)

您还违反了严格的别名规则


与您的问题无关,"%p"如果您想打印指针,您应该使用该格式。

于 2015-08-12T08:20:41.103 回答
2

当您使用*p = *p + 1;pbeeing a进行操作时double*,实际上有很多事情要做已更改(变为双重表示),这就是您获得这样结果的原因。printf

我运行代码并获得以下输出:

205afc2c,205afd28
205afc2c,593b4ab0
205afc2c,0

它显示使用该值作为双精度值无效,并且当它增加时,它不会更新sizeof(int)双精度值的第一位(因为它在最后一行打印 0)。

希望我说清楚了!

编辑

我稍微更改了代码以向您展示实际发生的情况:

void incme(double *p)
{
    printf("%x,%lf\n",p,*p);
    *p = *p + 1;
    printf("%x,%lf\n",p,*p);
}
int main()
{
    int i = 1;
    incme((double *)&i);    
    printf("%x, %lf, %d",&i,i, i);
}

给我以下输出:

cb90990c,0.000000
cb90990c,1.000000
cb90990c, 1.000000, 0

如您所见,如果将它们打印为双精度值,则该值确实是正确的(但二进制表示形式1.000000000000001我之前所说的不同,这就是为什么十六进制格式会为您提供很大的数字)。回到主界面,如果您将值显示为双精度值(如果 i 应该是 int 则为事件),因为incme函数更改了它的内存布局,它会打印 1.0000,但该地址处内存的前 32 位是0 因此,将其打印为 int 会给您 0。

于 2015-08-12T08:27:26.257 回答
0

主要原因,printf 语句应该是 -

printf( "%p,%f", p, *p );

这将显示您的双倍增量。

另外 - 如前所述,一个 int 通常是 4 个字节,而一个 double 使用 8 个字节。(在大多数系统上)

于 2015-08-12T08:26:14.650 回答