我想了解为什么以下代码不起作用...请帮助:
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 ......
答案 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个字节。 (在大多数系统上)