为什么这个指针传递不按预期工作?

时间:2015-08-12 08:13:47

标签: c pointers pass-by-pointer

我想了解为什么以下代码不起作用...请帮助:

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
它打破了我对指针所知的一切......

感谢。

编辑:

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

3 个答案:

答案 0 :(得分:3)

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

您还打破strict aliasing rule

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

答案 1 :(得分:2)

当你*p = *p + 1;进行double*时会有很多事情发生,实际上,当你使用{{1}时,使用自定义格式(wiki)代表双倍在此之后将其显示为整数,此地址处的内存表示已更改(为双重表示),这就是您获得此类结果的原因。

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

printf

它表示使用该值作为double无效,并且当它递增时,它不会更新double的205afc2c,205afd28 205afc2c,593b4ab0 205afc2c,0 个第一位(因为它在最后一行中打印0)。

希望我明白了!

修改

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

sizeof(int)

给我以下输出:

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);
}

正如您所看到的,如果您将它们打印为double,则该值确实是正确的(但cb90990c,0.000000 cb90990c,1.000000 cb90990c, 1.000000, 0 的二进制表示形式不是1.0000,正如我之前所说,这就是十六进制格式化给出的原因你很多)。 回到main中,如果你将值显示为double(事件,如果我应该是一个int),因为00000000001函数改变了它的内存布局,它确实打印1.0000,但是前面的32位是此地址的内存为0,因此将其打印为int会给出0。

答案 2 :(得分:0)

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

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

这将显示你的双倍增量。

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