3.4 初识复杂的表达式
显然,表达式++ n和n ++的值是不一样的。也正是利用了这一点,前面的while语句可以进一步改写为:
while(n <= r) { sum = sum + n ++; }
在这里,表达式sum = sum + n ++涉及三种运算符,运算符“++”在这里的优先级最高,“+”次之,“=”的优先级最低。因此,运算符++的操作数是n;运算符+的操作数是子表达式n ++的值和中间那个sum的值;运算符=的操作数则是sum + n ++的值和左值sum。说到底,这还是一个赋值表达式,等价于sum =(sum +(n ++)),而且这个表达式还有更新变量sum和n的存储值的副作用。
在第1章里我们已经强调过,操作数的值计算要先于运算符的值计算,也就是先要计算操作数的值,再得到运算符的结果。在这里,要得到表达式sum = sum + n ++的值(也就是运算符=的结果)就必须先计算子表达式sum + n ++的值;要计算表达式sum + n ++的值(也就是运算符+的结果)就必须先计算子表达式sum和n ++的值。子表达式sum的值是其左值转换后的值;子表达式n ++的值是变量n递增前的原值。
所以,表达式sum = sum + n ++的功能是将变量n递增前的原值和变量sum的值相加,结果依然保存到变量sum中。该表达式具有两个副作用,一是修改变量sum的存储值;二是递增变量n的存储值。
在while语句的累加过程中,每次都是先用变量n递增前的原值和变量sum的原值相加,结果再存回变量sum,表达式sum = sum + n ++正是利用了后缀递增运算符的一个特点:该运算符的值是其操作数递增前的原值。
在第1章里我们就已经给出了while语句的语法,也知道它的循环体不要求非得是复合语句。在这里,复合语句的花括号内只有一条表达式语句,在这种情况下花括号是可有可无的,还不如将花括号去掉,就像这样:
while(n <= r) sum = sum + n ++;
我们知道C语言对程序的格式不做特殊要求,因为这个while语句很简单,占用两行似乎太浪费空间了,用一行来书写就行:
while(n <= r)sum = sum + n ++;
所有赋值运算符的优先级相同,包括赋值运算符=和赋值运算符+=,但后者比前者在用法上更简洁。为此,我们甚至可以这样改写上述while语句:
while(n <= r)sum += n ++;
在这里,表达式sum += n ++是将表达式n ++的值加到变量sum,等价于sum = sum+ n ++。
练习3.3
可以把表达式sum = sum + n ++改成sum = sum + ++ n吗?为什么?上机验证你的想法(重点是看结果是否正确)。