background image

j 和m 的值均由表达式求得, 并且这两个表达式均由自增运算符、加法运算符和赋值运

算符组成。那么, 它们的值到底为多少呢? j=1+1+1=3 还是j=1+2+3=6? 
m=2+3+4=9 还是m=4+4+4=12?上机运行结果为: i=4,j=3,m=12。

分析: 

运算符 ++”,“+” “

和 =”的优先级是递减的, 在计算时,先进行自增运算, 再进行

加法运算, 

最后是赋值运算。而自增运算又根据 i++” “

和 ++i”的不同定义得到不同的值 。

i+++i+++i++先将i 原值(1)取出, 作为表达式中i 的值进行加法运算得到3, 然后再实现
三次自加; ++i+++i+++i 自加是在整个表达式求解之前开始,也即先对表达式扫描, 对i 
进行三次自加得到4, 再进行加法运算得到12。
例4

 main()

{ int i=1;
printf( “i=%d, j=%d\n”,i,i+++i+++i++);}

例5

 main()

{ int i=1
printf( “i=%d,m=%d\n”,i,++i+++i+++i);}
与前两个程序相似, 只不过将表达式移到了函数中作为实参实现调用, 上机运行得: 

i=4,j=6,m=9。j,m 的值发生了变化。这是因为在实现函数调用时, Turbo C 系统规定, 如
果实参中存在表达式, 则按右结合性来计算实参表达式。即运算对象先与右边的运算符结
合。i+++i+++i++即为1+2+3=6; ++i+++i+++i, 即为2+3+4=9

。所以当含 ++”

运算符的表达式作为实参实现调用时, 遵守右结合性原则。
例6
   设a=6, 求赋值表达式a+=a- =a- a*a 

的值。由于 *”(乘号) “

、 - ”(减号)

优先级高于 +

=” “

、 - =”,  “

且 *”

优先级高于 - ”, 故先求a- a*a, 即6- 6*6=- 30,  “

由 +=”,“- =”为同一

优先级, 且是从右至左的结合方向, 再求a- =- 30, 即a=a- (- 30)=6+30=36, 最后求
a+=36, 即a=a+36=36+36=72, 所以赋值表达式的值为a=72。
例7
   设m=1,n=2,b=3, 求赋值表达式m+=n- =- - - b 

的值。这里共有四个运算符 +=” “

、 - 

=” “

、 - ”(负号) “

、 - - ”, 由运算符优先级, 应先计算- - - b,  “

但 - - ” “

与 - ”(负号)优先级相同, 

如按从右到左的结合方向, 它可能是- (- - b), 也可能是- - (- b), 究竟是哪一个呢?前面已
讲过, 前置运算只能用于变量, 不能用于表达式, 而(- b)不是一个变量, 而是表达式, 故只
能是- (- - b), 即为- (3- 1)=- 2; 然后计算n- =- 2, 即n=n- (- 2)=2- (- 2)=4; 最后计算
m+=4, 即m=m+4=1+4=5, 所以赋值表达式的值m=5。

C 语言中运算符的两种不同的结合方向是其特有的, 理解结合方向有助于理解表达式

的运算顺序。当看到一个复杂的C 语言表达式时, 首先应按优先级进行运算, 然后在同一优
先级中按结合方向进行运算。而后者是初学者最易出错的, 本文通过若干典型实例分析, 希
望对读者理解C 语言运算符结合性有所帮助。
参考文献:
[1]谭浩强.C 程序设计( 第二版) [M].北京:清华大学出版社,
1999.
[2]刘祎玮,汪晓平.C 语言高级实例解析[M].北京:清华大学出
版社,2004.
[3]Herbert Schildt.著,戴健鹏.译.C 语言大全( 第二版) [M].北京:
电子工业出版社,1994.