C#入门经典(第7版):C# 6.0 & Visual Studio 2015(.NET开发经典名著)
上QQ阅读APP看书,第一时间看更新

4.1 布尔逻辑

第3章介绍的bool类型可以有两个值:true或false。这种类型常用于记录某些操作的结果,以便操作这些结果。特别是,bool类型可用于存储比较的结果。

注意:19世纪中叶的英国数学家乔治·布尔(George Boole)为布尔逻辑奠定了基础。

考虑下述情形(如本章引言所述):要根据变量myVal是否小于10来确定是否执行代码。为此,需要确定语句“myVal小于10”的真假,即需要了解比较的布尔结果。

布尔比较需要使用布尔比较运算符(也称为关系运算符),如表4-1所示。

表4-1 布尔比较运算符

在表4-1中,var1都是bool类型的变量,var2和var3则可以是不同类型。

在代码中,可以对数值使用这些运算符:

        bool isLessThan10;
        isLessThan10 = myVal < 10;

如果myVal存储的值小于10,这段代码就给isLessThan10赋予true值,否则赋予false值。也可以对其他类型使用这些比较运算符,例如字符串:

        bool isBenjamin;
        isBenjamin = myString == "Benjamin";

如果myString存储的字符串是Benjamin, isBenjamin的值就为true。也可以对布尔值使用这些运算符:

        bool isTrue;
        isTrue = myBool == true;

但只能使用==和!=运算符。

注意:一个常见的代码错误是,无意间假定由于val1 < val2是false,所以val1 > val2为true。如果val1 == val2,则这两条语句都是false。

&和 | 运算符也有两个类似的运算符,称为条件布尔运算符(见表4-2)。

表4-2 条件布尔运算符

这些运算符的结果与&和 | 完全相同,但得到结果的方式有一个重要区别:其性能比较好。两者都是检查第一个操作数的值(表4-2中的var2),如果已经能判断结果,就根本不处理第二个操作数(表4-2中的var3)。

如果&&运算符的第一个操作数是false,就不需要考虑第二个操作数的值了,因为无论第二个操作数的值是什么,其结果都是false。同样,如果第一个操作数是true, || 运算符就返回true,不必考虑第二个操作数的值。

4.1.1 布尔按位运算符和赋值运算符

使用布尔赋值运算符可以把布尔比较与赋值组合起来,其方式与第3章中的数学赋值运算符(+=、*=等)相同。布尔赋值运算符如表4-3所示。当表达式使用赋值(=)和按位运算符(&、|、^)时,就使用所比较数值的二进制表示来计算结果,而不是使用整数、字符串或相似的值。

表4-3 布尔赋值运算符

例如,等式var1 ^ = var2类似于var1 = var1 ^ var2,其中var1 = true、var2 = false。当比较false的二进制表示0000与true(一般不是0000的任何值,通常是0001)时,var1就设置为true。

注意:&=和 |= 赋值运算符并不使用&&和 || 条件布尔运算符,即无论赋值运算符左边的值是什么,都处理所有操作数。

在下面的示例中,用户键入一个整数,然后代码使用该整数执行各种布尔运算。

试一试:使用布尔运算符: Ch04Ex01\Program.cs

(1)在目录C:\BegVCSharp\Chapter04下创建一个新的控制台应用程序Ch04Ex01。

(2)将以下代码添加到Program.cs中:

            static void Main(string[] args)
            {
              WriteLine("Enter an integer:");
              int myInt = ToInt32(ReadLine());
              bool isLessThan10 = myInt < 10;
              bool isBetween0And5 = (0 <= myInt) && (myInt <= 5);
                WriteLine($"Integer less than 10? {isLessThan10}");
                WriteLine($"Integer between 0 and 5? {isBetween0And5}");
                WriteLine($"Exactly one of the above is true?
                          {isLessThan10 ^ isBetween0And5}");
                ReadKey();
              }

(3)运行应用程序,出现提示时,输入一个整数,结果如图4-1所示。

图4-1

示例说明

前两行代码使用前面介绍的技术,提示并接受一个整数值:

        WriteLine("Enter an integer:");
        int myInt = ToInt32(ReadLine());

使用Convert.ToInt32()从字符串输入中得到一个整数。Convert.ToInt32()是另一个类型转换命令,与前面使用的Convert.ToDouble()命令属于同一系列。ToInt32()和ToDouble()方法是System. Convert静态类的一部分。如第3章所述,自从C# 6之后,就可以在包括的名称空间列表中包含using static System.Convert类,直接访问静态类(在这个例子中是System.Convert)的方法。还要注意,没有检查用户是否输入了一个整数。如果提供了不是整数的值,例如字符串,在试图执行转换时会发生异常。可以使用try{ }…catch{ }块处理这种情况,或在执行转换之前使用GetType()方法,检查输入的值是不是一个整数。这两种方法将在后续章节讨论。

接着声明两个布尔变量isLessThan10和isBetween0And5,并赋值,其中的逻辑匹配其名称中的描述:

        bool isLessThan10 = myInt < 10;
        bool isBetween0And5 = (0 <= myInt) && (myInt <= 5);

接着在下面的3行代码中使用这些变量,前两行代码输出它们的值,第3行对它们执行一个操作,并输出结果。在执行这段代码时,假定用户输入了7,如图4-1所示。

第一个输出是操作myInt < 10的结果。如果myInt是6,则它小于10,因此结果为true。如果MyInt的值是10或更大,就会得到false。

第二个输出涉及较多计算:(0 <= myInt) && (myInt <= 5),其中包含两个比较操作,用于确定myInt是否大于或等于0,且小于或等于5。接着对结果进行布尔AND操作。输入数字6,则(0 <=myInt)返回true,而(myInt <= 5)返回false,最终结果就是(true) && (false),即false,如图4-1所示。

最后,对两个布尔变量isLessThan10和isBetween0And5执行逻辑异或操作。如果一个变量的值是true,另一个是false,则代码返回true。所以只有myInt是6、7、8或9,才返回true,本例输入的是6,所以结果是true。

4.1.2 运算符优先级的更新

现在要考虑更多的运算符,所以应更新第3章中的运算符优先级表,把它们包括在内,如表4-4所示。

表4-4 运算符优先级(更新后)

该表增加了好几个级别,但它明确定义了下述表达式该如何计算:

        var1 = var2 <= 4 && var2 >= 2;

其中&&运算符在<=和>=运算符之后执行(在这行代码中,var2是一个int值)。

这里要注意的是,添加括号可以使这样的表达式看起来更清晰。编译器知道用什么顺序执行运算符,但人们常会忘记这个顺序(有时可能想改变这个顺序)。上述表达式也可以写为:

        var1 = (var2 <= 4) && (var2 >= 2);

通过明确指定计算的顺序就解决了这个问题。