3.3 switch语句的使用及注意事项
虽然多重if语句可以替代switch语句,但是在某些时候使用switch语句使代码具有更好的可读性,避免了使用过多的if-else语句让人眼花缭乱。在讲解使用switch语句的注意事项之前,先来看看它的使用格式。
switch(表达式){
case常量表达式1:
语句段1;
[break]
case常量表达式2:
语句段2;
[break]
……
case常量表达式n:
语句段n;
[break]
default:
语句段n+1;
[break]
}
下面来了解一下switch语句的执行过程。首先计算出表达式的值,如果某个case后面的常量表达式N(N=1,2,……,n)的值等于switch语句中表达式的值,那么就执行该case后面的语句段N。值得注意的是,如果语句段N的后面有break,那么执行完语句段N后就退出switch语句,否则将继续往下执行,直到遇到break,如果没有break,那么将执行到最后一条switch语句。
1.break语句的使用
为了加深读者对switch语句执行过程的印象,接下来看一下如图3-7所示的switch语句流程图。
图 3-7 switch语句流程图
通过上面的流程图,我们能够直观地看出switch语句的执行过程。接下来看看如何使用switch语句。用switch语句编写前面用多重if语句实现的输入学生的数学成绩并进行分类的程序,代码如下:
include<stdio.h>
void main(void)
{
int score;
printf("请输入学生的数学成绩:");
scanf("%d",&score);
if(score>100||score<0)
{
printf("输入出错!\n");
return;
}
switch(score/10){
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
printf("学生成绩类别为:差\n");
break;
case 6:
printf("学生成绩类别为:及格\n");
break;
case 7:
printf("学生成绩类别为:中\n");
break;
case 8:
printf("学生成绩类别为:良\n");
break;
default:
printf("学生成绩类别为:优\n");
}
return;
}
运行结果:
请输入学生的数学成绩:29
学生成绩类别为:差
通过上面的运行结果可以发现,输入29时输出的类别为“差”。现在来分析一下这段代码中的switch语句的执行流程,先计算29整除10等于2,表达式的值为2,常量表达式为2的case后面没有任何语句段,那为什么能够输出正确的类别呢?这是因为在该语句段后面没有使用break来终止switch语句的执行,所以程序继续向下遍历常量表达式3和常量表达式4,直到常量表达式5,此时语句段后有break,所以程序执行完输出后退出了switch语句的执行。
2.常量表达式的使用
在使用switch语句的时候还要注意的一点是,常量表达式必须由常量所构成,不能含有变量。同时,常量表达式的值必须互不相同,也就是说,同一个常量在switch语句中只能对应一种处理方案。在switch语句中,除了使用整型常量作为常量表达式之外,还可以使用字符。下面的代码实现的功能为:从键盘输入一个英文字符,不区分大小写,通过switch语句判断该字符是否为元音字符。
include<stdio.h>
include<conio.h>
void main(void)
{
char ch;
printf("按下esc键即可结束运行!\n");
while(1)
{
printf("请输入字符:");
if((ch=getch())==27)
break;
putchar(ch);
if(ch>='a'&&ch<='z')
{
ch=ch-'a'+'A';
}
if(ch<'A'||ch>'Z')
{
printf("\n输入出错!请重新输入.\n");
continue;
}
switch(ch){
case'A':
case'E':
case'I':
case'O':
case'U':
printf("\n该字符为元音字符!\n");
break;
default:
printf("\n该字符非元音字符!\n");
}
}
return;
}
运行结果:
按下esc键即可结束运行!
请输入字符:4
输入出错!请重新输入.
请输入字符:d
该字符非元音字符!
请输入字符:O
该字符为元音字符!
请输入字符:u
该字符为元音字符!
请输入字符:
为了便于处理,我们将输入的英文字符转换为大写。看上面的运行结果,因为一开始输入的数据不是所要的测试类型,所以提示出错信息,继续输入数据。continue语句在此处的作用就是结束本次循环,直接进入下一次循环。
在混合使用字符和整数作为常量表达式的时候,更要注意常量表达式的值不能重复出现,如:
include<stdio.h>
include<conio.h>
void main(void)
{
char ch;
printf("请输入需要测试的大写字符:");
ch=getch();
putchar(ch);
switch(ch){
case 65:
case 69:
case'I':
case'O':
case'U':
printf("\n该字符为元音字符!\n");
break;
default:
printf("\n该字符非元音字符!\n");
}
return;
}
运行结果:
请输入需要测试的大写字符:A
该字符为元音字符!
在这里把前面代码中的常量表达式'A'和'B'分别改写成了它们的ASCII码65和66,其功能与前面使用'A'和'B'是等价的,因此在使用字符型常量的时候要留意其ASCII码值不能重复出现在常量表达式中。如果在''case 65:''前面加上一句''case A:'',那么在编译的时候会出现“error C2196:case value'65'already used”错误提示信息。
3.switch语句的嵌套
通过前面对switch语句的介绍,我们发现switch语句与if语句非常相似。if语句可以实现嵌套,switch语句同样可以实现嵌套功能,接下来我们就来看看switch语句的嵌套。switch语句嵌套的一般形式为:
switch(表达式1){
case常量表达式1:
switch(表达式2){
case常量表达式21:
语句段1;
[break]
case常量表达式22:
语句段2;
[break]
……
case常量表达式2n:
语句段n;
[break]
default:
语句段2n+1;
[break]
}
[break]
case常量表达式2:
语句段2
[break]
……
case常量表达式n:
语句段n
[break]
default:
语句段n+1
[break]
}
下面通过一段代码来介绍switch语句嵌套的使用,这段代码的功能是显示班级总分前三名同学的各科成绩,科目包括数学(m)、英语(e)、语文(c)。
include<stdio.h>
include<conio.h>
void main(void)
{
char ch;
int num;
printf("请输入学生的名次num(取值为1、2、3):");
num=getch();
putchar(num);
printf("\n请输入所要查询的科目前面ch(取值为m(数学)、e(英语)、c(语文)):");
ch=getch();
putchar(ch);
printf("\n");
switch(num){
case'1':
switch(ch){
case'm':
printf("数学成绩为:98\n");
break;
case'e':
printf("英语成绩为:97\n");
break;
case'c':
printf("语文成绩为:95\n");
break;
default:
printf("输入出错!\n");
return;
}
break;
case'2':
switch(ch){
case'm':
printf("数学成绩为:98\n");
break;
case'e':
printf("英语成绩为:89\n");
break;
case'c':
printf("语文成绩为:87\n");
break;
default:
printf("输入出错!\n");
return;
}
break;
case'3':
switch(ch){
case'm':
printf("数学成绩为:98\n");
break;
case'e':
printf("英语成绩为:78\n");
break;
case'c':
printf("语文成绩为:75\n");
break;
default:
printf("输入出错!\n");
return;
}
break;
default:
printf("输入出错!\n");
}
return;
}
运行结果:
请输入学生的名次num(取值为1、2、3):2
请输入所要查询的科目前面ch(取值为m(数学)、e(英语)、c(语文)):e
英语成绩为:89
分析上面的代码可知,在使用switch语句嵌套的过程中须注意break语句的使用。在switch语句的嵌套使用中,break语句仅仅是终止当前的switch语句,而不是完全退出整个多重switch语句。