表5.6 部分运算符的优先级和结合性
运算符种类 运 算 符 结 合 方 向 优 先 级 逻辑运算符 ! 高 ++ - - + - * ( 单目 ) 从右向左(右结合) 算术运算符 * / % ( 双目 ) + - ( 双目 ) < <= > >= 关系运算符 == ! = 从左向右(左结合) && 逻辑运算符 || 条件表达式 ? : 赋值运算符 = += -= *= /= %= 从右向左(右结合) 逗号运算符 . 从左向右(左结合) 低 例如,表达式-5 + 3 % 2等价于(-5)+(3 % 2 ),结果为-4;表达式3 * 5 % 3等价于 (3*5)% 3,结果为0,这是因为5两侧运算符 * 和 % 的优先级相同,按从左到右的结合方向,5先与 * 结合。而表达式 – i ++ 等价于 – ( i ++ ),这是因为i 两侧运算符 - 和 ++ 的优先级相同,按从右到左的结合方向,i 先与 ++ 结合。 4、算术表达式
用算术运算符将运算对象连接起来的符合C语言语法规则的式子称为算术表达式,运算对象包括常量、变量和函数等表达式。算术表达式的值和类型由参加运算的运算符和运算对象决定。 5、副作用的说明
(1)C语言中,自增和自减是两个很特殊的运算符,相应的运算会得到两个结果。例如:设n = 3,表达式 n ++ 经过运算之后,其值为3,同时变量n的值增1为4。即在求解表达式时,变量的值改变了,称这种变化为副作用。在编程时,副作用的影响往往会使得运算的结果与预期的值不相符。
要慎用自增、自减运算,尤其不要用它们构造复杂的表达式。
(2)C语言中,根据运算符的优先级和结合性决定表达式的计算顺序,但对运算符两侧操作数的求值顺序并未做出明确的规定,允许编译系统采取不同的处理方式。例如,计算表达式f( ) + g( ) 时,可以先求f( )再求g( ),也可以相反。如果求值顺序的不同影响了表达式的结果,即相同的源程序在不同的编译系统下运行,结果可能不同,就给程序的移植造成了困难。所以,在实际应用中应该避免这种情况。 5.5.2 赋值表达式 1、赋值运算服
C语言将赋值作为一种运算,赋值运算符 ” =” 的左边必须是一个变量,作用是把一个表达式的值赋给一个变量。赋值运算符的优先级比算术运算符低,它的结合方向是从右向左,见表5.6所示。例如,表达式x = ( 3 * 4 ) 等价于x = 3 * 4。表达式x = y = 3等价于x = ( y = 3 )。 2、赋值表达式
13
用赋值运算符将一个变量和一个表达式连接起来的式子称为赋值表达式。赋值表达式的简单形式是: 变量 = 表达式;
赋值表达式的运算过程是:
(1)计算赋值运算符右侧表达式的值。
(2)将赋值运算符右侧表达式的值赋给赋值运算符左侧的变量。
(3)将赋值运算符左侧的变量的值作为赋值表达式的值。
在赋值运算时,如果赋值运算符两侧的数据类型不同,在上述运算过程的第(2)步,系统首先将赋值运算符右侧表达式的类型自动转换成赋值运算符左侧变量的类型,再给变量赋值,并将变量的类型作为赋值表达式的类型。
例如,设n是整型变量,计算表达式 n = 3.14 * 2的值,首先计算3.14 * 2得到6.28,将6.28转换成整型值6后赋给n,该赋值表达式的值是6,类型是整型。
又如,设x是双精度浮点型变量,计算表达式x = 10 / 4的值,首先计算10 / 4得到2,将2转换成双精度浮点型值2.0后赋给x,该赋值表达式的值是2.0,类型是双精度浮点型。
在赋值表达式中,赋值运算符右侧的表达式也可以是一个赋值表达式。如:
x = ( y = 3 ); 求解时,先计算表达式y = 3,再将该表达式的值3赋给x,结果使得x和y都赋值为3;相当于计算x = 3和y = 3两个赋值表达式。
由于赋值运算符的结合性是从右到左,因此,x = ( y = 3 )等价于x = y = 3,即多个简单赋值运算可以组合为一个连赋值的形式。 3、复合赋值运算符
赋值运算符分为简单赋值运算符和复合赋值运算符。简单赋值运算符就是” = “,复合赋值运算符又分为复合算术赋值运算符和复合位赋值运算符,在” = “前加上算术运算符就构成了复合算术赋值运算符,见表5.7所示。复合位赋值运算符在5.5.7节介绍。
所以,赋值表达式的一般形式是: 变量 赋值运算符 表达式; 表5.7 复合算术赋值运算符
运 算 符 名 称 等 价 关 系 ( exp 指表达式 ) + = 加赋值 x + = exp等价于 x = x + ( exp ) - = 减赋值 x - = exp等价于 x = x – ( exp ) * = 乘赋值 x * = exp等价于 x = x * ( exp ) / = 除赋值 x / = exp 等价于 x = x / ( exp ) % = 求余赋值 x % = exp等价于 x = x % ( exp ) 注:exp指数表达式
x * = y – 3等价于x = x * ( y – 3 ),而不是x = x * y – 3
5.5.3 关系表达式 1、关系运算符
关系运算符(见表5.8所示)是双目运算符,用于对两个操作数进行比较。 表 5.8 关系运算符
运 算 符 < < = > > = = = ! =
名 称 小于 小于或等于 大于 大于或等于 等于 不等于 优先级 高 低
14
关系运算符的优先级低于算术运算符,高于赋值运算符和逗号运算符,它的结合方向是从左向右(见表5.6)。例如,设a、b、c是整型变量,ch是字符型变量,则: (1)a > b = = c等价于 ( a > b ) = = c (2)d = a > b等价于 d = ( a > b )
(3)ch > ? a ? + 1等价于ch > ( ? a ? + 1 ) (4)d = a + b > c等价于 d = ( ( a + b ) > c ) (5)3 < = x <= 5等价于( 3 < = x ) < = 5 (6)b – 1 = = a ! = c等价于(( b – 1 ) = = a ) ! = c 2、关系表达式
用关系运算符将两个表达式连接起来的式子,称关系表达式。关系表达式的值反映了关系运算(比较)的结果,它是一个逻辑量,取值“真”或“假”。由于C语言没有逻辑型数据,就用整数1代表“真”,0代表“假”。这样,关系表达式的值就是1或0,它的类型是整型。
例5.7 关系表达式的运用 #include
{ char ch = 'w'; // w 的ASCII码十进制为119 int a = 2,b = 3,c = 1,d,x = 10;
printf(\//a不大于b为假得0 ,而0是不等于c(c=1)的,所以结果是假0 printf(\//a不大于b得假0,而0 赋给d,d是0,结果是0
printf(\// 'a'是97,加1为98。ch为w值是119。119大于98,结果是真1 printf(\// a+b是5,5是大于c的,得真1,真1赋给d,结果是真1 printf(\// b-1得2,2等于a得真1,1应得c(1),但这里是!=故得假0 printf(\// 3小于10,得真1,而1小于5得真1,所以结果是真1。 return 0;
}
运行结果:0 0 1 1 0 1
程序输出了6个表达式的值,其中有两个是赋值表达式,请读者根据运算符的优先级做出判断。
关系表达式b – 1 = = a ! = c等价于关系表达式(( b – 1 ) = = a ) ! = 1,当a = 2,b = 3时,( b – 1 ) = = a的值是1,再计算1!= 1,得到0。
关系表达式3 <= x <= 5等价于关系表达式( 3 <= x ) <= 5,当 x = 10时,3 <= x的值是1,再计算1 <= 5,得到1。其实,无论x取什么值,关系表达式3 <= x的值不是1就是0,都是小于5,即3 <= x <= 5的值恒为1。由此看出,关系表达式3 <= x <= 5无法正确表示代数式3 <= x <= 5,如x = 4,3小于4,它得真是1,而1小于5得真,这不是代数式的表示,只是一种关系的运算。 5.5.4 逻辑表达式 1、逻辑运算符
15
C语言提供了3种逻辑运算符(见表5.9所示),逻辑运算对象可以是关系表达式或逻辑量,逻辑运算的结果也是一个逻辑量,与关系运算一样,用整数1代表“真”,用0代表“假”。
表5.9 逻辑运算符
目 数 单 目 双 目 运算符 ! && || 名 称 逻辑非 逻辑与 逻辑或
例如,在逻辑表达式( x >= 3 ) && ( x <= 5 )中,&&是逻辑运算符,关系表达式x >= 3和x <= 5是逻辑运算对象,逻辑运算对象的结果是1或0。
假如a和b是逻辑量,则对a和b可以进行的基本逻辑运算包括 ! a ( 或 ! b )、a && b和a || b 3种。作为逻辑量,a或b的值只能是“真”或“假”,所以,a和b可能的取值组合只有4种,即(“真”,“真”)、(“真”、“假”)、(“假”,“真”)和(“假”,“假”),与之对应的3种逻辑运算的结果也随之确定。将这些内容用一张表格表示,就是逻辑运算的“真值表”,见表5.10所示。它反映了逻辑运算的规则,其中a和b的取值见括号中的内容。
表 5.10 逻辑运算的“真值表”
a b ! a a && b a || b 非 0 (真) 非 0 (真) 0 1 1 非 0 (真) 0 (假) 0 0 1 0 (假) 非 0 (真) 1 0 1 0 (假) 0 (假) 1 0 0 表5.10说明了逻辑运算符的功能,即:
(1)! a :如果a为“真”,结果是0 ( 假 );如果a为“假”,结果是1(真)。 (2)a && b:当a和b都为“真”时,结果是1 ( 真 );否则,结果是0 ( 假 )。 (3)a || b:当a和b都为“假”时,结果是0 ( 假 );否则,结果是1( 真 )。
如何判断逻辑量(如a和b)的真、假呢?如果某个逻辑量的值为非0,就是真;如果值为0就是假(见表5.10所示)。
例如计算(x >= 3)&&(x <= 5),若x = 4,则 x >= 3和 x <= 5的值都是1(非0为真),“逻辑与”运算的结果就是1;若x = 10,则x >= 3的值是1(非0为真),而 x <= 5的值是0(假),“逻辑与”运算的结果就是0。 又如,计算 ! ( x = = 2 ),若x = 10,则x = = 2的值是0(假),“逻辑非”运算的结果是1(真);若x = 2,则 x = = 2的值是1(非0为真),“逻辑非”运算的结果是0(假)。
逻辑运算符的优先级见表5.6。例如: (1)a || b && c等价于a || ( b && c ) (2)! a && b等价于( ! a ) && b
(3)x >= 3 && x <= 5等价于( x >= 3 ) && ( x <= 5) (4)! x == 2等价于( ! x ) == 2
(5)a || 3 + 10 && 2等价于a || (( 3 + 10 ) && 2 ) 2、逻辑表达式
16

