18. C Primer Plus 7.7多重选择:switch和break语句

7.7多重选择:switch和break

使用条件运算符和if else 语句很容易编写二选一的程序。然而,有的程序需要在多个选项中进行选择。可以用if else if...else来完成。但是,大多数情况下使用switch语句更为方便。

下列示例程序演示了如何使用switch语句:


输出结果如下:

该程序读入一个字母,然后打印出与该字母开头的动物名。

该程序的两个主要特点是:使用了switch语句和它对输出的处理。我们来分析一下switch语句工作的原理。

7.7.1switch语句

要对紧跟在关键字 switch 后圆括号中的表达式求值。在程序清单 7.11 中,该表达式是刚输入给 ch的值。然后程序扫描标签(这里指,case 'a' :、 case 'b' :等)列表,直到发现一个匹配的值为止,然后程序跳转至那一行。如果没有匹配的标签,但是程序中有default:标签行,就跳转至该行;否则,程序则继续执行在switch之后的语句
break语句在其中的作用是:它让程序离开switch语句,跳至switch语 句后面的下一条语句。如果没有break语句,就会从匹配标签开 始执行到switch末尾。如果删除该程序中所有的break语句,运行程序后输入d,其交互后输出结果如下:

下图为switch语句中有break语句和无break语句的程序流:

1.有break语句:

2.无break语句:

如上所示,执行了从case 'd':到switch语句末尾的所有语句。

break语句可用于循环和switch语句中,但是continue只能用 于循环中。尽管如此,如果switch语句在一个循环中,continue便可作为 switch语句的一部分。这种情况下,就像在其他循环中一样,continue让程序跳出循环的剩余部分,包括switch语句的其他部分。

C语言中的switch语句和Pascal中的case语句类似,它们 最大的区别在于,如果只希望处理某个带标签的语句,就必须在switch语句 中使用break语句。另外,C语言的case一般都指定一个值,不能使用一个范围。

switch在圆括号中的测试表达式的值应该是一个整数值(包括char类 型)。case标签必须是整数类型(包括char类型)的常量或整型常量表达式 (即,表达式中只包含整型常量)。不能用变量作为case标签。

switch语句的结构:

switch(整型表达式)

{

case常量1:

语句 <--可选

case常量2:

语句 <--可选

default: <--可选

语句 <--可选

}

7.7.2只读每行的首字符

程序清单7.11的程序的另一个独特之处是它读取输入的方式。运行程序时输入“dab”时,只处理了第一个字符。这种丢弃一行中其他字符的行为,经常出现在响应单字符的交互程序中,下面的代码可以实现这一过程:

循环从输入中读取字符,包括按下Enter键产生的换行符。注意,函数 的返回值并没有赋给ch,以上代码所做的只是读取并丢弃字符。由于最后丢 弃的字符是换行符,所以下一个被读取的字符是下一行的首字母。在外层的 while循环中,getchar()读取首字母并赋给ch。

假设用户一开始就按下Enter键,那么程序读到的首个字符就是换行符。下面的代码处理这种情况:

7.2.3多重标签

可以在switch语句中使用多重标签,下列示例程序演示了switch语句中有多重标签的情况:

假设如果ch是字母i,switch语句会定位到标签为case 'i' :的位置。由于 该标签没有关联break语句,所以程序流直接执行下一条语句,即i_ct++;。 如果 ch是字母I,程序流会直接定位到case 'I' :。本质上,两个标签都指的是 相同的语句。

严格地说,case 'U'的 break 语句并不需要。因为即使删除这条 break 语 句,程序流会接着执行switch中的下一条语句,即default : break;。所以,可 以把case 'U'的break语句去掉以缩短代码。但是从另一方面看,保留这条 break语句可以防止以后在添加新的case(例如,把y作为元音)时遗漏break 语句。

该程序输出结果为:

在该示例程序中,可以使用ctype.h系列的toupper()函数可以避免使用多重标签,在进行测试之前就把字母转换成大写字母,如:

或者,可以先不转换ch,把toupper(ch)放入switch的测试条件中,如:

switch(toupper(ch))。

总结:带多重选择的switch语句

关键字:switch

一般注解:程序根据expression的值跳转至相应的case标签处。然后,执行剩下的所 有语句,除非执行到break语句进行重定向。expression和case标签都必须是 整数值(包括char类型),标签必须是常量或完全由常量组成的表达式。如 果没有case标签与expression的值匹配,控制则转至标有default的语句(如果 有的话);否则,将转至执行紧跟在switch语句后面的语句。

形似:

switch(expression)

{

case label1:statement1 //使用break语句跳出switch语句

case label2:statement2

default :statement3

}

可以有多个标签语句,default语句可选。

示例:

如果choice的值是1或2,打印第1条消息;如果choice的值是3,打印第2 条和第3条消息(程序继续执行后续的语句,因为case 3后面没有break语 句);如果choice的值是4,则打印第3条消息;如果choice的值是其他值只 打印最后一条消息。

7.7.4switch和if else

怎么选择何时使用switch、何时使用if else语句。我们经常会别无选择。

1.如果时根据浮点类型的变量或表达式来选择,就无法使用switch。

2.如果变量在某范围内决定程序流的去向,使用switch语句会很麻烦,这种情况使用if语句会更方便,例如:

使用switch语句要覆盖上述范围的话,需要为每个整数(3~999)设置case标签。但是,如果使用switch语句,程序通常运行快一些,生成的代码少一些,更为简单和可读。

posted @ 2022-02-07 00:32  喻雅芬  阅读(320)  评论(0)    收藏  举报