
3.3 分支语句
C++语言中提供了两种分支语句,即if语句和switch语句。其中,if语句多用于单分支条件判断,switch语句用于多分支条件判断。本节将详细介绍这两种分支语句。
3.3.1 if语句
if语句通常用于单分支条件判断。其简单的语法格式如下:

其中,else部分的语句是可选的。if语句的执行过程为:首先判断表达式的真假,如果为真,则执行语句1,否则执行else部分的语句(如果存在else语句)。例如,下面的if语句均是合法的。

注意
在if语句的表达式中,有时在使用“==”运算符时,程序员很容易将“==”运算符写成“=”运算符,由于这两个运算符都是合法的,因此编译器无法检测到这样的错误。在编程时一定要谨慎使用“==”运算符,否则将给您带来无尽的烦恼。
使用上述的if语句只能进行简单的逻辑条件判断。考虑如下的一种情况:学生成绩大于60的为及格、大于80的为良、大于90的为优秀,如何在程序中判断学生成绩呢?分析如下代码。

在上面的代码中存在多个缺点:(1)代码执行效率较低,因为程序会逐一执行每一个if语句,例如,如果ivar的值为59。当程序执行完“if(ivar < 60)”语句后,还需要执行“if (ivar >= 60 && ivar< 80)”“if (ivar >= 80 && ivar < 90)”等if语句。(2)判断条件比较复杂,上述代码中使用了多个区域判断。图3.1描述了上述代码的执行情况。
在C++中,if语句除了提供else子句外,还提供了else if子句。使用else if子句时,if语句的执行过程为:首先判断if条件表达式的真假,如果为真,则执行if部分的语句,然后整个if语句结束。如果为假,则继续判断else if语句中表达式的真假;如果为真,则执行else if部分的语句,if语句结束,否则继续向下判断。下面的代码使用else if子句对之前的学生成绩判断代码做了修改。
【例3.3】 成绩等级判断。

从上述代码可以看出,通过使用else if语句,不但提高了代码执行效率,还简化了区域判断的条件,使代码更加简洁。图3.2描述了上述代码的执行情况。
为了描述复杂的逻辑条件,if语句还允许嵌套,即if语句中包含if语句。例如,下面的代码利用嵌套的if语句来进一步判断成绩是否进行了确认。
【例3.4】 嵌套的if语句。


图3.1 if语句流程图1

图3.2 if语句流程图2
对于上述代码,还可以修改为如下形式。但是,用户在开发程序时,建议使用上述代码格式。

在上面的代码中注意else子句,这里else子句是与“if (checked)”语句对应的,即采用就近原则,else子句与其之前最近的if语句对应,尽管没有使用复合语句分隔。
3.3.2 switch语句
switch语句用于多分支条件判断,它能够测试一组有序类型(整型、字符型和枚举型等)的数据。当发现匹配的常量时,它将执行与该常量关联的语句。
switch语句的语法格式如下:

其中,表达式必须是有序类型,不能是实数或字符串类型。表达式逐一与case语句部分的常量匹配,如果发现有常量与表达式相匹配,则执行当前case部分的语句,直到遇到break语句位置,或者到达switch语句的末尾(没有遇到break语句)。当表达式没有发现与之匹配的常量,将执行default部分的代码。default语句是可选的,如果代码中没有提供default语句,并且没有常量与表达式匹配,switch语句将不执行任何动作。下面的代码利用switch语句判断数据库的当前状态。
【例3.5】 使用switch语句判断数据库的状态。(实例位置:资源包\TM\sl\3\1)

执行上述代码,结果如图3.3所示。
在switch语句中,如果需要对各个常量进行相同的处理,则可以将多个case语句组织在一起,使用一个执行语句。
【例3.6】 在switch语句中对多个常量进行相同的处理。(实例位置:资源包\TM\sl\3\2)

switch语句中的break语句属于跳转语句,也可以用于循环语句中。在switch语句中,当遇到break语句时,程序将跳转到switch语句之后的下一行代码处。如果在switch语句中没有使用break语句,当表达式与某个常量匹配时,将执行当前case语句代码,并且继续向下执行case语句的代码,直到遇到break语句或者switch语句结束。观察如下代码:
【例3.7】 switch语句的执行顺序。(实例位置:资源包\TM\sl\3\3)

执行上述代码,结果如图3.4所示。

图3.3 switch语句1

图3.4 switch语句2
由于在switch语句中没有使用break语句,当表达式dbste与close常量匹配时,没有遇到break语句,并且switch语句没有结束,因此继续向下执行,执行了其后的所有switch语句。
注意
在开发程序时,这通常不是预期的结果,因此在编写switch语句时,除非程序需要,否则不要遗忘break语句。