background image

C语言运算符的结合性分析

C 语言与其他高级语言相比, 一个显著的特点就是其运算符特别丰富, 共有34 种运算

符。C 语言将这34 种运算符规定了不同的优先级别和结合性。优先级是用来标识运算符在
表达式中的运算顺序的, 在求解表达式的值的时候, 总是先按运算符的优先次序由高到低
进行操作, 可是, 当一个运算对象两侧的运算符优先级别相同时, 则按运算符的结合性来确
定表达式的运算顺序。

运算符的结合性指同一优先级的运算符在表达式中操作的组织方向, 即: 当一个运算

对象两侧运算符的优先级别相同时, 运算对象与运算符的结合顺序, C 语言规定了各种运
算符的结合方向( 结合性) 

。大多数运算符结合方向是 自左至右 , 即: 先左后右, 例如a- 

b+c, b 两侧有- 和+两种运算符的优先级相同, 按先左后右结合方向, b 先与减号结合, 执
行a- b 的运算, 再执行加c 的运算。除了自左至右的结合性外, C 语言有三类运算符参与运
算的结合方向是从右至左。即: 单目运算符, 条件运算符, 以及赋值运算符。关于结合性的概
念在其他高级语言中是没有的, 这是C语言的特点之一,特别是从右至左结合性容易出错, 
下面通过几个具体的运算符来剖析C 语言运算符的结合性。

若a 是一个变量, 则++a 或a++和- - a 或a- - 分别称为前置加或后置加运算和前置

减或后置减运算, 且++a 或a++等价于a=a+1, - - a 或a- - 等价于a=a- 1, 即都是使该
变量的值增加1 或减少1。由此可知, 对一个变量实行前置或后置运算, 其运算结构是相同
的, 但当它们与其他运算结合在一个表达式中时, 其运算值就不同了。前置运算是变量的值
先加1 或减1, 然后将改变后的变量值参与其他运算, 如x=5; y=8; c=++x*y; 运算后, c 
的值是48,x 的值是6,y 的值是8。而后置运算是变量的值先参与有关运算, 然后将变量本身
的值加1 减1, 即参加运算的是该变量变化前的值。如x=5; y=8; c=x++*y;运算后, c 的
值是40,x 的值是6, y 的值是8。值得注意的是, 前置、后置运算只能用于变量, 不能用于常
量和表达式, 且结合方向是从右至左。如当i=6 时, 求- i++的值和i 

的值。由于 - ”(负号) 

“++”为同一个优先级, 故应理解为- (i++), 又因是后置加, 所以先有- i++的值为- 6, 然
后i 增值1 为7, 即i=7。
例1 main()
{int a=3,b=5,c;
c=a*b+++b;
printf ( “c=%d”, c);}

要得出c 的值, 首先要搞清+++的含义。++运算符的结合方向是自右向左的, 如果将

表达式理解为:c=a*b+(++b);实际上C 编译器将表达式处理为:c=(a*b++)+b, 因为C 
编译器总是从左至右尽可能多地将若干个字符组成一个运算符, 如i+++j 等价于(i++)
+j。接下来是解决a*b++的问题, 因为++运算符的运算对象只能是整型变量而不能是表
达式或常数, 所以a*b++显然是a*(b++)而非(a*b)++, 因此整个表达式就是c=(a*(b+
+))+b。
例2 main()
{ int i=1,j;
j=i+++i+++i++;
printf( “i=%d,j=%d\n”, i,j);}
例3 main()
{ int i=1,m;
m=++i+++i+++i;
printf( “i=%d,m=%d\n”, i,m);}