在GCC编译 a++

来源:互联网 发布:java telnet登录失败 编辑:程序博客网 时间:2024/06/04 17:51

在《Linux C编程一站式学习》一书中讲到,a = (++a)+(++a)+(++a)+(++a);的结果是 Undefined。
gcc测试下,a初始化为1,结果输出为15。
虽然知道这4个++a的执行前后是不能确定的,只能依据具体的编译器。
可想不通的地方:肯定要执行这4个++a,可顺序不同对于这个表达式来说,并不影响其结果吧。也就是说可以写成a = 2 + 3 + 4 + 5;(顺序随意),也就是说a的值是14。
请问多出的那个1是哪来的?

解答:

先看下面的

#include

int main(void)
{
int a = 1;
printf("%d/n",(++a)+(++a));
a = 1;
printf("%d/n",(++a)+(++a)+(++a)+(++a));
a = 1;
printf("%d/n",((++a)+(++a))+((++a)+(++a)));
a = 1;
printf("%d/n",(++a)+(++a)*(++a)+(++a)); /* 应该理解是4+4*4+5 */
a = 1;
printf("%d/n",(++a)+(++a)*(++a)*(++a)); /* 应该理解是5+4*4*5 */
return 0;
}
输出为:
6
15
16
25
85

自己猜想下:C语言变量操作以指针实现。(++a)+(++a),第一个(++a)之后,a的值变为2,参与在加法操作的是指针p,第二个(++a)后,a的值变为3,参与操作的是指针p,*p+*p。也就是3+3了。
(3+3已经只能做右值,所以,后面依次加4,加5。)

可能是(后面为什么依次加4,5?为什么不是5+5+5+5?我觉得解决这个问题应该看汇编代码)
这是对3L的理解。

(++a)+(++a)*(++a)+(++a)的猜测:跟上面同理,只不过加上了个*,因为*高于+,所以第一个(++a)一直在等,直到可以加一个右值。

我在想会不会因为对称导致上面的猜想看起来挺完美,所以我又尝试了(++a)+(++a)*(++a)*(++a),发现跟猜想的一样。

总结起来就是:在gcc下,(++a)的走向是从左到右的,每一个(++a)直到遇见可以做右值的表达式停下,进行计算。而这过程是以指针来控制的。 

原创粉丝点击