《c primer plus》p104中讲到:

副作用是对数据对象或文件的修改

c的主要目的是对表达式求值

c标准规定,在顺序点,所有的副作用都在进入下一步前被计算(顺序点是修改值的最晚时刻,有可能比它早)

 

3类顺序点:

1.每个完整表达式结束后,即分号后面
2.&&,||,三木运算符(?:),以及逗号表达式的每一个运算对象计算之后
3.函数调用中对所有实际参数的求值完成之后(进入函数体之前)

 

b=a++;对于这一语句,先求a++这个子表达式的值,然后求(这个值赋给b)的值,遇到分号顺序点,最迟在这里完成a修改值和b修改值的操作。

int a=0;int b=(a=a++);这一语句执行后a的值是0,b也是0。个人理解:先把a的值赋给某一内存区域,然后求(这个区域赋值给a)这个表达式的值,注意只是求表达式的值,未必已经赋值,即修改左值,然后求这个表达式赋给b这个表达式的值,最后遇到分号,最迟在这里3个副作用生效,既然最后a是0,那么说明先a的值修改为1,然后那个内存区域存的原来的a赋给a,使得a还是0,然后赋表达式的值给b。注意,表达式语句的值是右值。

int a=0;a=(a++)+(a++);执行后a的值是1,个人理解过程:先考虑主要目的即表达式求值,再考虑副作用。先执行两个a++,存到其他内存区域值均为0,赋给a这个表达式值为0,然后修改一次a,再完成赋值给a的动作,现在a是0,最后一次修改a为1.

int a=0;a=(a++)+(++a);执行后a的值是2,个人理解先执行++a,a为1,然后a++,1赋给某一区域,()+()的值是2但不赋给a,然后a修改+1为2,最后赋值给a2.

 

 

上c语言课时,老师讲谭浩强书上的一个语句a+=a*=a-=a最后结果是0;感觉有问题,老师讲的计算表达式时直接修改值,但实际上可能;时才修改值,但是结果确实是0,说明执行副作用是也是从右向左的。