![C# 8.0本质论](https://wfqqreader-1252317822.image.myqcloud.com/cover/306/43475306/b_43475306.jpg)
4.5 布尔表达式
if语句中包含在圆括号内的部分是布尔表达式,称为条件。代码清单4.28突出显示了条件。
代码清单4.28 布尔表达式
![](https://epubservercos.yuewen.com/7885FF/22815793809130806/epubprivate/OEBPS/Images/d4.28.jpg?sign=1738883153-smG1G1mWOW1HZ2IcyldqiPoohDbfZ9DB-0-904d56e166546bafb6f60f26264c628f)
许多控制流程语句都要使用布尔表达式,其关键特征在于总是求值为true或false。input<9要成为布尔表达式就必须返回bool值。例如,编译器不允许将布尔表达式写成x=42,因为它的作用是对x进行赋值,并返回新值,而不是检查x的值是否等于42。
语言对比:C++——错误地使用=来代替==
C#消除了C/C++的一个常见的编码错误。代码清单4.29在C++中不会出错。
代码清单4.29 C++允许将赋值作为条件
![](https://epubservercos.yuewen.com/7885FF/22815793809130806/epubprivate/OEBPS/Images/d4.29.jpg?sign=1738883153-Sq9wNUXQ1Sltdpy8TEaAvKL0mWooHKm4-0-45985dcf2546cf69fc9a50ca616d9c43)
虽然上述代码表面上是检查input是否等于9,但正如第1章讲过的那样,=代表的是赋值操作符,而不是检查相等性的操作符。从赋值操作符返回的是赋给变量的值,本例中就是9。然而,作为int的9无法被判定为布尔表达式,所以是C#编译器不允许的。C和C++将非零整数视为true,将零视为false。相反,C#要求条件必须是布尔类型,不允许整数。
4.5.1 关系操作符和相等操作符
关系和相等操作符判断一个值是否大于、小于或等于另一个值。表4.2总结了所有关系和相等操作符。它们都是二元操作符。
表4.2 关系和相等操作符
![](https://epubservercos.yuewen.com/7885FF/22815793809130806/epubprivate/OEBPS/Images/4b2.jpg?sign=1738883153-Yd7wy0o3HKhCrTrrBiiTBvTif3vrE0SX-0-c6ed59e68ed5257a40e59341dca84c5a)
和其他许多编程语言一样,C#使用相等操作符==来测试相等性。例如,判断input是否等于9要使用input==9。相等操作符使用两个等号,赋值操作符则使用一个。C#的惊叹号代表NOT,所以用于测试不等性的操作符是!=。
关系和相等操作符总是生成bool值,如代码清单4.30所示。
代码清单4.30 将关系操作符的结果赋给bool变量
![](https://epubservercos.yuewen.com/7885FF/22815793809130806/epubprivate/OEBPS/Images/d4.30.jpg?sign=1738883153-VLaOSgz3HmzZI957sQ6D3ArwOUdtmHQG-0-9191cf1683d1776eca9cf8a139262dc0)
井字棋程序的完整代码清单使用相等操作符判断玩家是否退出游戏。代码清单4.31的布尔表达式包含一个OR(||)逻辑操作符,下一节将详细讨论它。
代码清单4.31 在布尔表达式中使用相等操作符
![](https://epubservercos.yuewen.com/7885FF/22815793809130806/epubprivate/OEBPS/Images/d4.31.jpg?sign=1738883153-6KMfzA5WqqyBWyynvvhNoYUsJQwkd7Hr-0-f7211b54b9f9b714e4039ff78e2ccd80)
4.5.2 逻辑操作符
逻辑操作符获取布尔操作数并生成布尔结果。可用逻辑操作符合并多个布尔表达式来构成更复杂的布尔表达式。逻辑操作符包括|、||、&、&&和^,对应OR、AND和XOR(异或)。OR和AND的|和&版本很少用,原因稍后讨论。
OR操作符
在代码清单4.31中,如果玩家输入quit,或直接按回车键而不输入任何值,就认为想退出程序。为了允许玩家以两种方式退出,程序使用了逻辑OR操作符||。||操作符对两个布尔表达式进行求值,任何一个为true就返回true,如代码清单4.32所示。
代码清单4.32 使用OR操作符
![](https://epubservercos.yuewen.com/7885FF/22815793809130806/epubprivate/OEBPS/Images/d4.32.jpg?sign=1738883153-0GNq84JLGeRtT8hwBkuDvAyj4eOPrfLi-0-3ad5654fcf851c90cb94af6e037f1c03)
注意使用布尔OR操作符时,不一定每次都要对操作符两边的表达式进行求值。和C#的所有操作符一样,OR操作符从左向右求值,所以假如左边求值为true,那么右边可以忽略。换言之,如hourOfTheDay的值为33,那么(hourOfTheDay > 23)会返回true,所以OR操作符会忽略右侧表达式。这种短路求值方式同样适合布尔AND操作符。注意,此处不需要括号,逻辑操作符的优先级低于关系操作符。然而,对于新手读者来说,在子表达式中加括号更为清晰。
AND操作符
布尔AND操作符&&在两个操作数求值都为true的前提下才返回true。任何操作数为false都会返回false。
代码清单4.33判断当前小时数是否大于10且小于24[1]。如同时满足这两个条件,就输出一条消息表明当前是工作时间。和OR操作符一样,AND操作符也并非每次都要对右边的表达式进行求值。如左边的操作数返回false,则不管右边的操作数是什么,最终结果肯定为false,所以“运行时”会忽略右边的操作数。
代码清单4.33 使用AND操作符
![](https://epubservercos.yuewen.com/7885FF/22815793809130806/epubprivate/OEBPS/Images/d4.33.jpg?sign=1738883153-A3LVC8QQ88yZrOsXXD6upuQCrmCNLQTj-0-8d213108545e631d75e36f76eb0af24e)
XOR操作符
^符号是异或(Exclusive OR,XOR)操作符。若应用于两个布尔操作数,那么只有在两个操作数中仅有一个为true的前提下,XOR操作符才会返回true,如表4.3所示。
与布尔AND和OR操作符不同,布尔XOR操作符不支持短路运算。它始终都要检查两个操作数,因为除非确切知道两个操作数的值,否则不能判定最终结果。注意将表4.3的XOR操作符换成!=操作符,结果完全一样。
表4.3 XOR运算表
![](https://epubservercos.yuewen.com/7885FF/22815793809130806/epubprivate/OEBPS/Images/4b3.jpg?sign=1738883153-s23iOtbHjQK6fyI6fTdXzBo6zBV2KqhM-0-35f5361e89c64f133ef9a43e5ca33c2f)
4.5.3 逻辑求反操作符
逻辑求反操作符(!)有时也称为NOT操作符,作用是反转一个bool数据类型的值。它是一元操作符,只需一个操作数。代码清单4.34演示了它如何工作,输出4.16展示了结果。
代码清单4.34 使用逻辑求反操作符
![](https://epubservercos.yuewen.com/7885FF/22815793809130806/epubprivate/OEBPS/Images/d4.34.jpg?sign=1738883153-Eqr8e9HToCYK1fsweNTGf0AnhrLZ065P-0-aaf0ab17a026b2fa95267b2340f52c77)
输出4.16
![](https://epubservercos.yuewen.com/7885FF/22815793809130806/epubprivate/OEBPS/Images/s4.16.jpg?sign=1738883153-Zt0ST4bQBTT2bPsAnMe6MAqWbXX1BNIf-0-0290e929b6c1b3b2439727c0925eab03)
valid最开始的值为false。求反操作符对valid的值取反,将新值赋给result。
4.5.4 条件操作符
可用条件操作符取代if-else语句来选择两个值中的一个。条件操作符同时使用一个问号和一个冒号,常规格式如下:
![](https://epubservercos.yuewen.com/7885FF/22815793809130806/epubprivate/OEBPS/Images/126-i.jpg?sign=1738883153-BHmo9PGl1TEchXE1ELtIaBIHFi7xrGIp-0-77f68e358b1249eed4e3348644c14555)
条件操作符是三元操作符,需要三个操作数:condition、consequence和alternative。(由于它是C#中唯一的三元操作符,因此通常称为三元操作符,但用它的名称来称呼它比用操作数数量更清楚。)类似于逻辑操作符,条件操作符也采用了某种形式的短路求值。如condition求值为true,则条件操作符只求值consequence;否则只求值alternative。操作符的结果是被求值的表达式。
代码清单4.35展示了如何使用条件操作符。该程序的完整清单是Chapter03\TicTacToe.cs。
代码清单4.35 条件操作符
![](https://epubservercos.yuewen.com/7885FF/22815793809130806/epubprivate/OEBPS/Images/d4.35.jpg?sign=1738883153-UEqWTEkwmkAVLxoITpw6W1wwx4j8N40V-0-4255916e88b04f5ff3dc4ddcbedf38a5)
程序作用是交换当前玩家。它检查当前值是否为2。这是条件语句的condition部分。如结果为true,条件操作符返回consequence值1;否则返回alternative值2。和if语句不同,条件操作符的结果必须赋给某个变量(或作为参数传递),不能自成语句。
设计规范
·考虑使用if/else语句而不是过于复杂的条件表达式。
C#语言要求条件操作符的consequence和alternative表达式类型一致,而且在判定类型时不会检查表达式的上下文。例如,f ? "abc" : 123不是合法的条件表达式,因为consequence和alternative分别是字符串和数字,相互不能转换。即使object result=f ? "abc" : 123;这样的语句,C#编译器也会认为非法,因为兼容两个表达式的类型(这里是object)在条件表达式的外部。
[1] 程序员典型的工作时间。