这个问题展开来说会很复杂,我说个大概,你还得去研究一下C标准和相关的文章。
关键词是C的求值顺序。
表达式求值顺序不同于运算结合性和优先级,q=(++j)+(++j)+(++j);这个式子没有顺序点,而++j和q=xxx这些操作都是有副作用(side-effect)的,而副作用的顺序不被保证(这是为了方便各编译器能自行优化代码)。所以最多只能保证执行完以后j=8,而q的值可能由于各编译器优化不同而产生不同结果,我使用gcc4.4.3得到22,你可以试试VC,turbo C,或许有别的结果。
使用gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3,把代码编译成汇编可以看得更明白:
movl $5, 40(%esp) # 40(%esp)是j在栈中的地址,j=5
addl $1, 40(%esp) # j=j+1=6
addl $1, 40(%esp) # j=j+1=7
movl 40(%esp), %eax # eax是累加用寄存器,把j放入寄存器
addl %eax, %eax # eax = eax + eax = 7 + 7 = 14 !!注意这里因为优化,对j进行了两次自增后才执行相加操作,因此结果不是我们想象中的6+7,而是7+7
addl $1, 40(%esp) # j=j+1=8
addl 40(%esp), %eax # eax = eax + j = 22。得到了22而不是21
建议你继续阅读下文,对求值顺序有更加细致精确的描述
http://blog.csdn.net/ox_thedarkness/article/details/613122
我算出来是p和q的值分别15和24。i和j的值都是8。而且我感觉这也是正确的答案。
p=(i++)+(i++)+(i++)的执行顺序是先执行括号内的,先执行5+5+5,然后i执行三次加一。最后i的值是8.
q=(++j)+(++j)+(++j)是先执行三次j加一,j的值变成8。在执行括号外的相加8+8+8=24。
我是在vs2003中执行了的。
#include
{int i=5,j=5,p,q;
p=(i++)+(i++)+(i++);
q=(++j)+(++j)+(++j);
printf("%d,%d,%d,%d",p,q,i,j);
p=5+6+7=18;
q=6+7+8=21;
一个是加完1后赋值,一个是赋值后加1,不过不知道为什么是22.