2.7 表达式和运算符

表达式,是由数字、算符、数字分组符号(括号)、自由变量和约束变量等以能求得数值的有意义排列方法所得的组合。表达式是运算符和操作符的序列。运算符是个简明的符号,包括实际中的加减乘除,它告诉编译器在语句中实际发生的操作,而操作数为操作执行的对象。运算符和操作数组成完整的表达式。

2.7.1 运算符类型

在大部分情况下,对运算符类型的分类都是根据运算符所使用的操作数的个数来分类的,一般可以分为如下3类。

一元运算符:只使用一个操作数,如(!);自增运算符(++)等,如i++。

二元运算符:使用两个操作数,如最常用的加减法,如i+j。

三元运算符:三元运算符只有一个(?:)。

除了按操作数个数来分以外,运算符还可以按照操作数执行的操作类型来分,见表2-5。

表2-5 常用的运算符

978-7-111-46863-9-Chapter02-30.jpg

1.算术运算符

算术运算符用于创建和执行数学表达式,以实现加、减、乘、除等基本操作,示例代码如下:

978-7-111-46863-9-Chapter02-31.jpg

注意:当除数为0,系统会抛出DivideByZeroException异常,在程序开发中应该避免出现逻辑错误,因为编译器不会检查逻辑错误,只有在运行中才会提示相应的逻辑错误并抛出异常。

2.关系运算符

关系运算符用于创建一个表达式,该表达式用来比较两个对象并返回布尔值。示例代码如下:

978-7-111-46863-9-Chapter02-32.jpg

关系运算符如“>”,“<”,“>=”,“<=”等同样是比较两个对象并返回布尔值。

初学者很容易错误的使用关系运算符中的“==”,因为初学者通常会将等于运算符编写为“=”,示例代码如下所示。

978-7-111-46863-9-Chapter02-33.jpg

在这里,运算符“=”不等于“==”。“=”的意义是给一个变量赋值,而“==”是比较两个变量的值是否相等。

3.逻辑运算符

逻辑运算符和布尔类型组成逻辑表达式。NOT运算符“!”使用单个操作数,用于转换布尔值,即取非。C#的与运算符是“&&”。该运算符使用两个操作数做与运算,当有一个操作数的布尔值为false时,则返回false。C#中也使用“||”运算符来执行或运算,当有一个操作数的布尔值为true时,则返回true。在逻辑运算符中还包括异或运算符“^”,该运算符确定操作数是否相同,若操作数的布尔值相同,则表达式将返回false。示例代码如下:

978-7-111-46863-9-Chapter02-34.jpg

注意:虽然C#不支持隐式的转换int到bool类型,但是Convert.ToBoolean静态方法提供了实现,任何非0的参数都将返回true。

4.位运算符

位运算符通常使用位模式来操作整数类型,这些位运算符非常实用。位运算符包括“<<”、“>>”、“&”、“|”、“^”和“~”。左移位运算符“<<”将整型中的位左移指定位数,每一次左移,整型变量的值将乘以2,左移操作将舍弃移出的所有位,并用0来填充移入的位。同样,右移运算符“>>”也将操作数右移,每一次右移,整型变量的值将除以“2”。“&”运算符通过逐位执行逻辑与运算,从而生成新的操作数,与运算中,两个对应的值,若有一个值为0,则全部为0。或运算符“|”的使用方法和原理和与运算符“&”基本相同,其区别在于使用的是或运算,当有一个值为1,则结果为1。异或运算符“^”的用法和与位运算符类似,其区别在于当两个值相同时,执行计算的结果为0,否则为1。取补运算符“~”将生成整型类型的补码。如原值中的1将变为0,而0则变为1。位运算符原理如图2-1~图2-5所示。

978-7-111-46863-9-Chapter02-35.jpg

图2-1 左移

978-7-111-46863-9-Chapter02-36.jpg

图2-2 AND位运算

978-7-111-46863-9-Chapter02-37.jpg

图2-3 OR位运算

978-7-111-46863-9-Chapter02-38.jpg

图2-4 XOR位运算

978-7-111-46863-9-Chapter02-39.jpg

图2-5 取补位运算

5.条件运算符

条件运算符“?:”需要3个操作数,示例代码如下:

978-7-111-46863-9-Chapter02-40.jpg

上述代码中,使用了条件运算符“?:”。条件运算符“?:”会执行第一个条件,若条件成立,则返回运算符“:”前的一个操作数的数值,否则返回运算符“:”后的操作数的数值。上述代码中,变量ifisTrue为true,则返回“true”。

2.7.2 运算符的优先级

开发人员需要经常创建表达式来执行应用程序的计算,简单的有加减法,复杂的有矩阵、数据结构等,在创建表达式时,往往需要一个或多个运算符。在多个运算符之间的运算操作时,编译器会按照运算符的优先级来控制表达式的运算顺序,然后再计算求值。表达式中常用的运算符的运算顺序见表2-6。

表2-6 运算符优先级

978-7-111-46863-9-Chapter02-41.jpg