前面我们所学的if(-else)结构可以用于根据不同的条件有选择性的执行不同的语句
但是,如果遇到有较多分支的语句,仍用if-else来处理时
你就需要写一堆的if-else结构,这样写显然很麻烦
在这种情况下,就该switch上场了
我们先来写这样一个程序:让用户输入一个范围在1-7的整数,并且根据这些数字输出周一至周七,1对应周一,2对应周二,依此类推。
请你首先写出一个使用if-else的版本
#include <stdio.h> #include <stdlib.h> int main() { int input; printf("请输入一个范围在1~7的整数:"); scanf("%d", &input); while(input > 7 || input < 1) { printf("输入无效,请重新输入:"); scanf("%d", &input); } if(1 == input) { printf("星期一\n"); } else if(2 == input) { printf("星期二\n"); } else if(3 == input) { printf("星期三\n"); } else if(4 == input) { printf("星期四\n"); } else if(5 == input) { printf("星期五\n"); } else if(6 == input) { printf("星期六\n"); } else { printf("星期天\n"); } return 0; }
可以看出来,这样写真的很长……
当然,这个程序还有另一种写法
#include <stdio.h> #include <stdlib.h> int main() { int input; printf("请输入一个范围在1~7的整数:"); scanf("%d", &input); while(input > 7 || input < 1) { printf("输入无效,请重新输入:"); scanf("%d", &input); } if(1 == input) { printf("星期一\n"); } else { if(2 == input) { printf("星期二\n"); } else { if(3 == input) { printf("星期三\n"); } else { if(4 == input) { printf("星期四\n"); } else { if(5 == input) { printf("星期五\n"); } else { if(6 == input) { printf("星期六\n"); } else { printf("星期天\n"); } } } } } } return 0; }
这两种的写法本质是相同的
而且正常人都看得出来,使用if-else来进行跳转,写起来实在是麻烦
那么switch又怎么用呢?
switch(表达式) { case 常量表达式1: //一些代码 case 常量表达式2: //另一些代码 default ://处理意外情况的代码 }
注意,一个表达式不一定要是一个式子,对于一个数字(如1)或者单独的一个变量foo,它们都是表达式
switch后的表达式的值便是你要判断的值,例如上面的程序中,我们可以写成
switch(input)
switch对于括号内的表达式有要求,它要求表达式的值是一个整型(或者其他能被转换为整型的类型)
对于浮点数,是不能够使用switch的!
这里的每一个case都是一个分支(case在英语中的意思有“情况”),其后面跟随的常量表达式的值便是其对应的值(我们称其为标号,label)
这里要求值是一个常量,例如1,2,3,当然’a’等字符也是可以的,因为它的实质也是数
但是你不能使用变量,甚至是const修饰的“常量”(如const int),类似于case foo的写法是不合法的
除case外,还有一个default,当switch里的值没有匹配与任何一个case时,将跳转到default。
一个switch中只允许有一个default
说了这么多,我们不如看一下代码
#include <stdio.h> #include <stdlib.h> int main() { int input; printf("请输入一个范围在1~7的整数:"); scanf("%d", &input); while(input > 7 || input < 1) { printf("输入无效,请重新输入:"); scanf("%d", &input); } switch(input) { case 1: { printf("星期一\\n"); break; } case 2: { printf("星期二\n"); break; } case 3: { printf("星期三\n"); break; } case 4: { printf("星期四\n"); break; } case 5: { printf("星期五\n"); break; } case 6: { printf("星期六\n"); break; } case 7: { printf("星期天\n"); break; } default:break; } return 0; }
是不是顿时觉得清晰很多呢?
和if等结构不同,switch中case后面的大括号不是必须的(不管它后面有多少个语句)
这是因为你可以通过下一个case标签很好的区分某一个语句属于哪一个case(即不会引起歧义,请思考if为何会有歧义)
接下来请看case内的代码,我们在每一个分支里都添加了一个break,这是多余的吗?
显然不是,这和switch的执行过程有关
假设上面的程序里我们输入了数字2;
那么switch会根据input(即2)的值跳转到case 2这个分支,然后执行内部的代码(这里是printf)
但是在执行完毕后,switch并不会跳出来执行switch结构后面的代码,而是顺着标号2所在的分支往下执行(即case 3内的代码)
倘若下面的分支都没有添加break,那么程序将会一直执行到标号为7的分支,接着是default内的代码,直到switch结束才会跳出
而加了break之后则会直接跳出switch,这才是我们(在这个程序中)需要的结果
请你删除break,再进行尝试
注意,没有break时执行的顺序和标号大小无关,和case和default也无关,而之和你程序的书写顺序有关
你可以任意的交换case(还有default)的顺序,但是通常我们都按照一定的顺序写,而且将default放在最后
default不是必须的,对于没有default的switch,在没有匹配到任何一个case时会直接跳到switch后面的代码执行
default通常是用于处理“非正常”情况的,在此程序中便是值不在1-7范围内的情况
因此,在这个程序中,我们可以删除default(因为在输入的地方我们便判断了输入值的大小)
但是,出于好习惯,你应该在任何一个switch中都写上default,哪怕你确定一定以及肯定它不会被执行(例如这个程序)
哪怕它确实无事可干!因为这样便说明你已经考虑过了其它的情况
最后,你可能会问,对于数值不是整数(如浮点数)时,又或者判断的是一个数是否在一个范围内又应该如何处理呢?
没有办法,对于复杂的判断,跳转,你只能使用if-else!
最后,请你做以下练习
- 删除判断input值的循环代码,并在default内给出提示(如果数不在1-7的情况下)
- 删除switch分支内的break,观察switch的执行
- 在上一个实验的前提下,调整几个case的顺序,并观察程序的执行
ps:因为case执行了不会自动跳出这个特性,我们可以写出下面的代码
#include <stdio.h> #include <stdlib.h> int main() { int input; printf("请输入一个范围在1~7的整数:"); scanf("%d", &input); while(input > 7 || input < 1) { printf("输入无效,请重新输入:"); scanf("%d", &input); } switch(input) { case 1: case 2: case 3: case 4: case 5: printf("工作日\n"); break; case 6: case 7: printf("休息日\n"); break; default:break; } return 0; }
很高兴能看到这么好的教程,太感谢了,呵呵