第三章 控制流 >> 3.4 switch语句
switch语句也是一个常用的多路判定语句,格式一般是:
switch (表达式) { case 常量表达式1: 语句序列1; case 常量表达式2: 语句序列2; ………… default: 语句序列n; }
其执行的过程是:先计算表达式的值,如果某一个分支的常量表达式与表达式的值匹配,则执行对应分支的语句序列;如果没有哪个分支与表达式的值匹配,则执行default分支的语句序列;
要注意:
- 常量表达式1、常量表达式2……各代表一个分支,这些常量表达式必须互不相同;
- default分支是可选的;(如果没有没有default分支,同时其他分支也都与表达式的值不匹配,则该switch语句不执行任何动作)
- 各分支(包括default分支)的排列顺序是任意的;
在第一章【从头学C(7) 数组】中,有一个用if-else结构写的程序,用于统计各个数字、空白符及其他字符的出现次数。用switch语句也可以完成同样的程序设计:
#include <stdio.h> /* count digits, white space, others */ int main() { int c, i, nwhite, nother, ndigit[10]; nwhite = nother = 0; for (i = 0; i < 10; i++) ndigit[i]= 0; while ((c = getchar()) != EOF) { switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': ndigit[c-'0']++; break; case ' ': case '\n': case '\t': nwhite++; break; default: nother++; break; } } printf("digits ="); for (i = 0; i < 10; i++) printf(" %d", ndigit[i]); printf(", white space = %d, other = %d\n", nwhite, nother); return 0; }
break语句可以让程序的执行立即从switch语句中退出来,而且从上面的例子我们可以看到,有的分支后面加了break,有的分支没有加break,而且有的分支后面是空的语句序列。
在switch语句中,case的作用只是一个标号。所以,某个分支的代码执行完成后,如果没有break或return语句使程序退出switch结构,那么程序会进入紧邻的下一个分支继续执行,这也是上面程序的第13、14行以及第17、18行的设计意图。
像这种将多个分支组合在一起的做法,有利也有弊。但正常情况下,我们在每个分支后面都会以一个break语句结束,因为从一个分支直接进入下一个分支继续执行的这种方法,在实际编程中很容易由于粗心而导致异常结果,而使得程序调试起来有点困难。所以一般不推荐这种做法,但在不得不使用的情况下,也应该加上适当的注释。
当我们把这个.c文件的所有字符交给这个程序去统计时(linux下可以使用命令 cat xxx.c | ./a.out),可以得到如下的结果:
digits = 10 4 1 1 1 1 1 1 1 1, white space = 158, other = 435
在switch语句的最后一个分支后面也加上一个break语句,虽然逻辑上没有必要这么做,但这是一种良好的程序设计风格。当我们需要在后面补充更多的分支时,这种编程习惯可以降低程序修改出错的可能性。