switch是一个专门用于处理多分枝的语句,在分支多的时候代替if语句简化代码。本文罗列一下switch的基本用法以及一些注意点,并且验证一些奇怪的地方。
本文代码在windows 8.1下使用Dev-c编写,测试。
一个样例
01 | #include <iostream> |
02 | #include <cstdio> |
03 | using namespace std; |
04 | #define LL long long |
05 | int x; |
06 | int main( void ) |
07 | { |
08 | while (cin>>x) |
09 | { |
10 | switch (x) //需要对比的值 |
11 | { |
12 | case 1: |
13 | puts ( " 1" ); |
14 | case 2: |
15 | puts ( " 2" ); |
16 | case 3: |
17 | puts ( " 3" ); |
18 | // case 常量: 比较x和常量值是否相等。 |
19 | // 执行语句; |
20 | default : //最后执行(后面详细说明) |
21 | puts ( " no" ); |
22 | } |
23 | } |
24 | return 0; |
25 | } |
运行一下这个代码,测试几个值后就能发现,switch是在拿x从上往下对比case中的值,如果匹配,则执行这个case之后的语句(注意是case之后,不是紧随case),如果值都没有匹配,则执行default后的语句。
特别注意:判定之后的执行
很多人随着if的逻辑,认为switch中的case判定之后就只执行紧随case的语句。准确的说是case之后的语句。相信对上面的代码执行以下就能发现。
01 | 1 |
02 | 1 |
03 | 2 |
04 | 3 |
05 | no |
06 | 2 |
07 | 2 |
08 | 3 |
09 | no |
10 | 3 |
11 | 3 |
12 | no |
13 | 4 |
14 | no |
输入1的时候,后面的puts语句都执行了。包括default后的语句。
所以,case匹配正确之后,在case之后的语句就会顺序执行下去,后面的case、default就被无视了。
关于break:
当然有时候并不希望这样直接执行下去,毕竟if,else if判断正确后只执行紧随着的代码块。所以,这里可以使用一个break语句。因为case判断正确之后,它不是会顺序执行下去么,那你执行到break时,就break(跳)出去了,也就不会执行后面的代码了。
几乎所有的代码都会在case后使用break语句。故意省略break语句是罕见的,因此应该提供注释说明逻辑。
实验代码:
01 | #include <iostream> |
02 | #include <cstdio> |
03 | using namespace std; |
04 | #define LL long long |
05 | int x; |
06 | int main( void ) |
07 | { |
08 | while (cin>>x) |
09 | { |
10 | switch (x) |
11 | { |
12 | case 1: |
13 | puts ( " 1" ); |
14 | case 2: |
15 | puts ( " 2" ); |
16 | break ; //这里加了break; |
17 | case 3: |
18 | puts ( " 3" ); |
19 | default : |
20 | puts ( " no" ); |
21 | } |
22 | } |
23 | return 0; |
24 | } |
测试结果:
01 | 1 |
02 | 1 |
03 | 2 |
04 | 2 |
05 | 2 |
06 | 3 |
07 | 3 |
08 | no |
09 | 4 |
10 | no |
关于default位置的实验:
按说,defualt应该放在所有case之后。但是我们发现,default放在case中间是可以的。那么放在case里面会如何执行,只有试一试才知道。
代码:
01 | #include <iostream> |
02 | #include <cstdio> |
03 | using namespace std; |
04 | #define LL long long |
05 | int x; |
06 | int main( void ) |
07 | { |
08 | while (cin>>x) |
09 | { |
10 | switch (x) //需要对比的值 |
11 | { |
12 | case 1: |
13 | puts ( " 1" ); |
14 | default : //default在此 |
15 | puts ( " no" ); |
16 | case 2: |
17 | puts ( " 2" ); |
18 | case 3: |
19 | puts ( " 3" ); |
20 | } |
21 | } |
22 | return 0; |
23 | } |
输入输出情况:
01 | 1 |
02 | 1 |
03 | no |
04 | 2 |
05 | 3 |
06 | 2 |
07 | 2 |
08 | 3 |
09 | 3 |
10 | 3 |
11 | 4 |
12 | no |
13 | 2 |
14 | 3 |
可以基本判断执行分为两步:
- 顺序判断case,忽略default,如果判断正确,顺序执行后面的语句(忽略case和default的判断)。
- 如果所有的case都不符合,则跳到defualt,然后顺序执行default后面的语句。
我们可以认为default是个特殊的case语句。
其它注意点:
特别注意在switch中定义变量。尽量不要在case语句之间定义变量。
- 风险:代码跳过变量的定义和初始化。造成变量未初始化。
- 规避方法:如果必须这样,建议使用块语句{},在块语句中定义变量并使用。
样例代码:
01 | #include <iostream> |
02 | #include <cstdio> |
03 | using namespace std; |
04 | #define LL long long |
05 | int x; |
06 | int main( void ) |
07 | { |
08 | while (cin>>x) |
09 | { |
10 | switch (x) |
11 | { |
12 | case 1: |
13 | puts ( " 1" ); |
14 | |
15 | default : |
16 | puts ( " no" ); |
17 | int a; //变量声明 |
18 | a=3; |
19 | case 2: |
20 | puts ( " 2" ); |
21 | cout<< "cas 2:" <<a<<endl; |
22 | case 3: |
23 | puts ( " 3" ); |
24 | } |
25 | } |
26 | return 0; |
27 | } |
测试结果:
1 | 2 |
2 | 2 |
3 | cas 2:33 #显然,这是未初始化的变量。 |
4 | 3 |
【关于break】里,样例代码中替换break为continue,也是有break的效果的。但是这个是因为外面有个while循环,去掉这个循环,是编译失败的。
转载请注明:旅途@KryptosX » C/C++中的switch语句使用注意