有朋友拿了一道C语言的题目如下:
结果data两次都是57,选对的同学已经可以叉掉这篇文章了。
上网查了很多解释,有说++写在后面,所以先赋值再++了,++写在前面才是先+1再赋值;有说return后面写++有语义错误,++不起作用了;还有说第一次调用+1了,第二次只赋值没调用的……
通过实际实践断点调试过后,发现其实是因为第二次convert先返回了一个data里的值57,这个57存放在了寄存器里,而data实际存放的数在convert函数刚刚结束的时候变成了58。接下来又因为赋值操作,把寄存器里的57赋值给了data,覆盖了58,所以最后data就还是57。convert起作用了,++也起作用了,只是寄存器里的值57又赋值回给data覆盖了58。
断点调试的代码如下:
(为了方便区别与测试,我将原题函数里的变量名data改成了p,并在之后用d来承接第二次调用函数后返回的值)
#include <stdio.h>
int convert(int* p)
{
return(*p)++;
}
main()
{
int data=56;
int d=0;
convert(&data);
printf("%d,",data);
d=convert(&data);
printf("%d,\n",data);
printf("d=%d\n",d);
}
这个结果为
57,58
d=57
也就是data实现了++操作变为了58,寄存器里的57赋给了d。
此外,return++(*p)和return(*p)++并没有什么区别。因为在完成convert之前执行步骤都不会跳出这个函数,而函数内又没有进行赋值操作,所以不会受到赋值和+1的影响。
return(++*p),才是先进行了+1操作,再返回+1操作完的数。
return(*p++)(结果如下图),则是对地址进行了+1操作,返回了*p原来的值56,++操作后*p指向了下一个地址存放的值,但没什么实际用处。
暂时还没有搞懂的是为什么和return((*p)++)(结果如下图)和return(*p)++结果一样,在我看来他不是应该先做+1操作再返回+1后的值吗?但这样的结果却跟return(*p)++一样,这个问题有待探究。如果有知道的朋友也可以帮忙回答下。
有兴趣的朋友可以自己试试看,我实在是有点榆木脑袋+菜,所以这么基础的东西也搞半天。第一次写文废话有点多,望见谅。