C语言基础要素(015):分支控制:switch 语句
switch 语句
switch语句是一种多路判定语句,它测试表达式是否与一些常量数值中的某一个值匹配,并执行相应的分支动作。
switch (表达式)
{
case 常量表达式:
语句序列
case 常量表达式:
语句序列
default:
语句序列
}
每一个由case语句表达的分支,都由一个整型常量或常量表达式
标记;如果某个分支与表达式的值匹配,则从该分支开始向后执行。
int a = 3;
switch (1)
{
case 1: printf("1\n"); // Ok:1是常量
case 2: printf("2\n"); // Ok:2是常量
case 'a': printf("'a'\n"); // Ok:'a'是常量
case a: printf("a\n"); // Error:a是变量
case 1.2: printf("1.2\n"); // Error:1.2不是整型常量
}
当前switch的表达式与 case 1 相匹配,所以整个switch语句从该分支开始执行。注释掉错误语句后,程序的输出结果或许有些意外,虽然程序仅与 case 1 匹配,但后续的case语句序列也被执行了。
我们可以想像编译器把上面的switch语句翻译成下面的图示:
- case中的所有标签在前面,语句序列在后面。
- tag值为1,是switch中表达式的值,与label #1匹配。
- 然后程序跳转到printf(“1\n”);处执行
- 完成后继续执行后面的语句
tag(1) ======> label #1: 1 -----------+ 匹配后跳转
label #2: 2 |
label #3: 'a' |
|
printf("1\n")<---------+
printf("2\n") | 向下继续执行
printf("'a'\n") |
v
switch语句中case分支表达式不能重复
。
switch (3 - 2)
{
case 1: printf("1\n"); // Ok:常量1
case 2: printf("2\n"); // Ok
case 1: printf("1\n"); // Error:已经存在常量标签1
}
switch语句可以有一个default语句,用于处理没有匹配到标签的情形。
int a = 'a';
switch (a)
{
case 'b': printf("b");
case 'c': printf("c");
default: printf("default"); // 执行这条语句
}
如果switch语句没有default分支也没有匹配到其他分支,则该switch语句不执行任何动作,所以下面的示例没有任何输出。
int a = 89;
int b = 72;
switch (a - b)
{
case 15: printf("15");
case 16: printf("16");
}
switch语句的各分支及default分支的排列次序是任意的
。
switch (2)
{
case 2: printf("2\n");
case 1: printf("1\n");
case 'a': printf("'a'\n");
default: printf("default\n");
}
输出:
2
1
'a'
default
注意,这里强调的是分支的排列次数,而不是程序执行结果。所以,你也可以这样排序匹配语句:
#include <stdio.h>
int main()
{
switch (2)
{
default: printf("default\n");
case 'a': printf("'a'\n");
case 2: printf("2\n");
case 1: printf("1\n");
}
printf("========================\n");
switch ('a')
{
case 2: printf("2\n");
case 'a': printf("'a'\n");
default: printf("default\n");
case 1: printf("1\n");
}
return 0;
}
switch语句的一组标签可以共享一段程序流程。下面的程序用于判断字符letter是否为元音字母(这里省略了大写字母的处理),就是运用了这种技巧。不过,由于switch语句在匹配分支后仍会向后执行的原因,程序在匹配元音字母后,仍会输出default分支的信息。
#include <stdio.h>
int main()
{
char letter = 'a';
printf("The letter '%c' is a ", letter);
switch (letter)
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
printf("vowel\n");
default:
printf("consonant\n");
}
printf("here...\n");
return 0;
}
break语句
终止switch分支语句向下流动的方法是使用break关键字。当分支执行了break语句后,所属的switch语句将被终止。
现在我们使用break语句修复上面的代码让它正确工作。
#include <stdio.h>
int main()
{
char letter = 'a';
printf("The letter '%c' is a ", letter);
switch (letter)
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
printf("vowel\n");
break;
default:
printf("consonant\n");
break;
}
printf("here...\n");
return 0;
}
练习
- 编写一个switch语句,让case分支执行多条语句。
- 编写一个switch语句,尝试在case中定义变量并随意模拟一些操作,看看程序的表现。
- 根据语法规则可以看到,case的语句序列也可是switch语句,尝试编写这样的程序。
- 探索一下switch与if语句的有什么异同。