
4.2 选择结构
选择结构是用来判断所给定的语句是否满足条件,根据判断结果,选择执行不同的分支语句。常用的语句有如下4种语句:if语句、if…else语句、多重if…else语句和switch语句。下面将详细介绍。

4.2.1 if语句
if语句为单分支条件语句,其说明语句的一般形式为:

其中,表达式可以是int型、long型、char型和enum型,其值有0和非0两种,0为false,非0为true。语句可以是任何类型的语句,也可以是块语句。该语句的作用是:如果表达式的值为true,则执行if后面的语句;否则跳过执行后面的语句。其执行顺序如图4-8所示。

图4-8 if语句执行流程
【范例4-7】if语句的应用。已知两个变量x和y,比较它们的大小,当x小于y时,交换这两个变量的值,使x的值大于y。实现程序如代码清单4-7所示。
代码清单4-7

【运行结果】在Visual C++中执行上述程序,其执行结果如图4-9所示。

图4-9 if语句
【范例解析】读者可以看到,在范例4-7程序代码中使用了if语句,当表达式x<y成立时,执行{}内的语句块,完成交换操作,使得变量x的值更大;当表达式x<y不成立时,则不执行{}内的任何操作,直接输出变量x和y的值,也使得变量x的值更大,这样就达到了示例的要求。
注意
if语句一般用于有多种可能的情况,但只有一种情况需要进行操作,即其他情况不需要进行程序控制的情况下。
4.2.2 if…else语句
if…else语句为双分支条件语句,其说明语句的一般形式为:

该语句的作用是:如果表达式的值为true,则执行语句1;否则执行语句2。相对于如上的if语句,if…else语句增加了对表达式的值为false时的处理语句,其执行流程如图4-10所示。

图4-10 if…else语句执行流程
【范例4-8】if…else语句的应用。该范例根据输入的学生的百分制成绩,判断该学生是否及格,其实现程序如代码清单4-8所示。
代码清单4-8

【运行结果】在Visual C++中执行上述程序,其执行结果如图4-11所示。

图4-11 用if…else语句执行程序的结果
【范例解析】范例4-8代码的结构非常清晰。定义接收用户输入分数的变量,给出提示信息,接收用户输入,再根据用户输入使用if…else语句判断是否及格。
提示
if…else语句一般用于两种情况,其一,根据其是否满足条件而分别执行不同的程序段;其二,在进行不同操作的情况下。
4.2.3 多重if…else语句
多重if…else语句为多分支条件语句或if…else if…else语句,其说明语句的一般形式为:

该语句形式中,首先测试表达式1,如果它为false,接着就测试表达式2,依此类推,直到找到一个为true的条件就执行相应的语句块,执行后即跳出该语句。如果所有的条件都不是true,则执行else语句块。其执行顺序如图4-12所示。

图4-12 多重if…else语句
注意
该语句为if语句的嵌套,在嵌套时,C++语言规定每个else只与其前面最近的未配对的if配对,也可以用{ }确定层次关系。
【范例4-9】多重if…else语句的应用。该范例输入学生的百分制成绩,判断该学生的等级。其等级评定条件如下:

读者可以看出该示例的等级有5种情况,因此可以使用多重分支语句if…else if…else来实现。其实现程序如代码清单4-9所示。
代码清单4-9

【执行结果】范例4-9程序代码使用了多重分支语句if…else if…else,根据用户输入的分数进行等级的判断,其程序执行结果如图4-13所示。

图4-13 用多重if…else语句执行程序的结果
【范例解析】范例4-9代码中,首先接收用户从键盘输入的分数,将其存入变量score中,再使用多重if…else语句判断该分数在哪一区间内,并对应输出不同的等级。
【范例4-10】读者可以发现,其实多重分支语句if…else if…else可以使用if语句的嵌套来实现。例如,针对上述示例,可以使用如代码清单4-10所示的程序来实现相同功能。
代码清单4-10

上述代码中使用了多重分支嵌套,其使用多个if…else语句的嵌套实现多重if…else语句的功能。在Visual C++ 6.0中运行上述代码,读者可发现其执行结果与图4-13相同。
警告
在实际使用中,一般不推荐使用多重分支嵌套,这是因为用多重分支嵌套时很容易出错,对于程序的可读性也有损害。
4.2.4 switch语句
switch语句也称情况语句,其也是一种多分支语句,其说明语句的一般形式为:

该语句的执行顺序是:首先计算switch表达式后的值,然后将其结果与case后面的各常量表达式进行比较。若匹配,则执行该分支后的语句,执行完后,遇到break语句,则退出switch语句;若其结果与case后面的各常量表达式都不匹配,则执行default后面的语句。其执行流程如图4-14所示。

图4-14 switch语句执行流程
【范例4-11】switch语句的应用。该范例输入0~6的整数,转换成“星期”输出。该范例可以使用switch语句来实现,也可以使用4.2.3节提到的多重分支和分支嵌套的方法来实现,为简单起见,这里只给出使用switch语句实现的程序代码,如代码清单4-11所示。
代码清单4-11

【运行结果】上述程序执行结果如图4-15所示。

图4-15 用switch语句执行程序的结果
【范例解析】范例4-11首先从键盘接收一个0~6之间的整型数值,将其存入变量day中,再根据day的值使用switch…case语句给出对应的输出,其与多重if…else语句的执行流程类似。
警告
在使用switch…case语句时,读者一定要注意使用break语句,否则将因无法跳出分支不能继续执行下去,从而导致输出错误。
在使用switch语句时应注意以下几点:
●若case后面没有break语句,则程序顺序执行后续的语句,直到switch语句结束。这样就不能实现多分支选择。
●switch语句只能对表达式的结果是否为固定的值进行判断,而不能对其结果是否在某区域进行判断,这与多重if…else语句有所不同。
●每个常量表达式的值不能相同,case语句的排列顺序不影响执行结果。
通过上述几种分支语句实现选择结构的介绍,读者可根据实际情况选择适当的语句。一般来说,应尽量使用可读性强的语句。
4.2.5 应用示例
4.2.1节~4.2.4节详细讲解了4种选择结构的实现语句,本节将通过一个较综合的示例回顾一下选择结构的实现。
【范例4-12】选择结构应用示例。该范例求方程ax2+bx+c=0的根。该程序的实现需要接收用户输入a、b、c,并根据输入判断是否有实根求出,实现代码如代码清单4-12所示。
代码清单4-12

【执行结果】上述程序中使用了多重分支语句if…else if…else语句来实现一元二次方程的根在三种不同情况下的取值,其执行结果如图4-16所示。

图4-16 一元二次方程求解
【范例解析】根据一元二次方程的求根公式(-b+sqrt(b*b-4*a*c))/(2*a),需要先根据(b*b-4*a*c)中的值判断其有几个根。根据其取值的不同,有三种不同情况:当(b*b-4*a*c)大于0时方程有两个根,等于0时有一个根,小于0时则没有实根。范例4-12即采用了if…else if…else语句实现了这三种情况的判断,使其根据取值不同,执行不同的程序。
注意
在一个if或else语句内,如果需要执行的代码多于1条语句,就必须用{}将其所有语句包含起来,构成复合语句。
为了便于读者理解上述范例,此处给出该范例的执行流程图,如图4-17所示。

图4-17 执行流程图