5.5 switch语句
除了if语句,C语言还提供了switch语句作为分支程序结构设计语句,有些版本也将switch语句称为“开关语句”。
5.5.1 switch语句的定义
编写程序时,经常会碰到按不同情况分支的多路问题。对于这类问题,可用嵌套if-else-if语句来实现,但过多的if-else-if嵌套语句不方便程序的阅读和维护,这时,就需要使用switch语句。switch语句的一般表达形式为:
switch(表达式) { case常量表达式1: 语句段1; case常量表达式2: 语句段2; …… case常量表达式n: 语句段n; default: 语句段n+1; }
switch语句的运行规则为:计算表达式的值,顺序与其后的常量表达式值相比较,当表达式的值与某个常量表达式的值相等时,即执行其后的语句段。语句段执行完毕后,不再进行判断,继续执行后面所有的case语句。
请注意,常量表达式一定是常量或常量构成的表达式,不能含有变量。
如表达式的值与所有case后的常量表达式均不相同时,则执行default后的语句。switch语句的执行流程图如图5-9所示。
图5-9 switch语句执行流程图
当语句段只有一条语句时,语句段可放在常量表达式的冒号后面,并且注意,冒号不可写成分号或逗号。当语句段有多条语句时,可以使用大括号封装,也可以不使用,这里我们约定,为便于程序阅读和理解,对多语句的程序段,一律使用大括号封装。
范例5.8 SwitchSentenceCase.c
SwitchSentenceCase.c键盘输入整型的星期数,打印出英文的星期名称字符串,根据键盘输入的星期数,打印出该星期数的英文名。使用switch语句实现,输入函数使用scanf函数,星期一的星期数记为1,星期天的星期数记为7。例如,输入2,应打印输出Tuesday。(光盘\chat5\ SwitchSentenceCase.c)
01 #include<stdio.h> 02 main() 03 { 04 int WeekNum=0; 05 printf("请输入星期数:\n"); 06 scanf("%d", &WeekNum); 07 switch(WeekNum) //判断输入参数类型 08 { 09 case 1: //为星期一的分支 10 printf("Monday\n"); 11 case 2: //为星期二的分支 12 printf("Tuesday\n"); 13 case 3: //为星期三的分支 14 printf("Wednesday\n"); 15 case 4: //为星期四的分支 16 printf("Thursday\n"); 17 case 5: //为星期五的分支 18 printf("Friday\n"); 19 case 6: //为星期六的分支 20 printf("Saturday\n"); 21 case 7: //为星期天的分支 22 printf("Sunday\n"); 23 default: //为错误的分支 24 printf("错误:您输入的参数不正确\n"); 25 } 26 }
程序第7行使用switch语句判断对不同输入应跳转的不同分支,按照不同的输入数据,程序输出对应的字符串,当输入数据不是1~7之间的数值时,输出错误提示信息。
程序运行时输入4,按回车键。
请输入星期数:
4
输出结果:
Thursday
Friday
Saturday
Sunday
错误:您输入的参数不正确
这里我们期望输入4时程序输出字符串Thursday并结束。然而,程序并没有按照我们设想的进行,而是将case 4之后的所有case语句都执行了一遍。这是由switch语句的规则决定的,当某个常量表达式与switch关键字后的表达式一致时,程序执行该case对应的语句段,并不加判断地继续执行后面的所有case及default语句段。
避免这种程序执行的方法是使用break语句。
5.5.2 break语句
为避免程序在switch语句中持续执行case语句,C语言提供了break语句。break语句仅有关键字,没有任何参数。它可以使switch语句在执行完一个case之后就跳出,从而避免了遍历case的可能。break语句的另外一个功能是跳出循环,将在第6章详细介绍。
需要说明的是,对于switch语句,应在每一个case语句之后都增加break语句,以使每一次执行相应语句段之后均可跳出switch语句,从而避免输出不必要的结果。如图5-10所示为switch语句中添加break语句的流程图。
图5-10 switch中添加break语句的流程图
5.5.3 switch语句的执行与应用
switch语句中,case后的各常量表达式的值不能相同,否则程序编译时会出现错误。此外,case的常量表达式后可不带任何语句,这样做的目的是使多种分支可以对应一个语句段。
范例5.9 SwitchSentenceWithBreak.c
SwitchSentenceWithBreak.c键盘输入学生成绩,分段显示不同成绩段的优劣,90<=score<=100为excellence, 80<=score<90为all right,70<=score<80为midding, 60<=score<70为pass, score<60为bad。(光盘\chat5\ SwitchSentenceWithBreak.c)
01 #include<stdio.h> 02 main() 03 { 04 int score=0; 05 printf("请输入分数值:"); 06 scanf("%d", &score); //输入参数score 07 if(0<=score&&score<=100) //判断是否符合实际 08 { 09 switch(score/10) //使用除法判断score范围 10 { 11 case 10: //并列执行 12 case 9: //并列执行 13 printf("excellence\n"); break; //添加break 14 case 8: 15 printf("all right\n"); break; 16 case 7: 17 printf("middling\n"); break; 18 case 6: 19 printf("bad\n"); break; 20 default: //默认执行 21 printf("错误:您输入的参数不正确\n"); 22 } 23 } 24 else //分支流程 25 { 26 printf("错误:您输入的参数不正确\n"); 27 } 28 }
程序第7行首先判断输入的数据是否符合实际,即是否属于0~100之间的数值,若不符合,则执行第24行的else分支,打印错误信息,并结束程序。若输入数据符合实际,则执行第9行,通过除法区分输入数值属于哪个数据段,从而根据不同的分支打印不同信息。另外,对每个case分支,程序使用了break语句用于跳出分支流程。
程序执行时输入数据98,按回车键。
请输入分数值: 98
输出为:
excellence
作者心得:
为书写方便,程序没有对每个case后的语句段进行括号封装,读者在编写程序时可自行添加,以保证程序正确性和可读性。
switch语句中,default语句主要用于当没有case和表达式匹配时输出错误信息。default语句可以省略,并且一般情况下,default中没有break语句。
此外,case语句在switch中的的位置和顺序并没有严格限制,可以任意调换。