## 選擇結構-Switch基本概念
### Switch基本格式
```
switch(表達式){
case 常量表達式1:
語句1;
break;
case 常量表達式2:
語句2; ...
break;
case 常量表達式n:
語句n;
break;
default:
語句n+1;
break;
}
```
> 其語義是:計算表達式的值。 并逐個與其后的常量表達式值相比較,當表達式的值與某個常量表 達式的值相等時, 即執行其后的語句,然后不再進行判斷,繼續執行后面所有case后的語句。
> 如表達式的值與所有case后的常量表達式均不相同時,則執行default后的語句。
- 示例:接收用戶輸入,控制臺打印菜名
```
int num;
printf("輸入一個1-7之間的數: ");
scanf("%d",&num);
switch (num){
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:
printf("error\n");
break;
}
```
## Switch注意事項
### case的穿透問題
- switch里面的case只要匹配一次其它的都失效,包括default. 正是因為switch的這個特性, 所以可能導致程序出現邏輯錯誤
- 為了避免上述情況,C語言還??供了一種break語句,專用于跳出switch語句,break語句只有關鍵字break,沒有參數。
+ 在每一case語句之后增加 break 語句, 使每一次執行之后均可跳出switch語句,從而避免輸出不應有的結果
+ 有時候也可用巧妙的利用case的穿透問題來簡化代碼
- 示例
```
int num;
printf("輸入一個1-7之間的數: ");
scanf("%d",&num);
switch (num){
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:
printf("error\n");
// break;
}
```
> 輸入1之后的輸出結果:
> 玉米炒葡萄
> 月餅炒辣椒
> 爆炒妙脆角
> 番茄炒鹵蛋
> 南瓜炒豬肝
> 蘋果炒西瓜
> 天地無極
> error
### switch條件類型
- 表達式的類型(case語句后的值)必須是整型或可以轉變為整型的值 (short、char和int類型)。
```
switch (10.10){ // 報錯
case 1:
printf("玉米炒葡萄\n");
break;
default:
printf("error\n");
break;
}
```
### case值的規定
- case的值必須是是整型或可以轉變為整型的值
```
switch (10){
case 1:
printf("玉米炒葡萄\n");
break;
case 'a': // 字符可以轉換為整型
printf("玉米炒葡萄\n");
break;
case 10.8: // 報錯
printf("玉米炒葡萄\n");
break;
default:
printf("error\n");
break;
}
```
- case的值1、值2...值n只能為常數或常量,不能為變量。
```
int num = 5;
switch (10){
case num: // 變量報錯
printf("玉米炒葡萄\n");
break;
default:
printf("error\n");
break;
}
```
- 如果在case后面定義的變量必須加上大括號
```
switch (10){
case num:{
int num = 5;
printf("num = %d", num);
break;
}
default:
printf("error\n");
break;
}
```
- switch中case后面的表達式的值不能相同
```
switch (10){
case 1:
printf("玉米炒葡萄\n");
break;
case 1: // 和上面相同報錯
printf("玉米炒葡萄\n");
break;
default:
printf("error\n");
break;
}
```
- case語句可以有任意多句,可以不用加括號“{}”
```
switch (10){
case 1:
printf("玉米炒葡萄1\n");
printf("玉米炒葡萄2\n");
break;
default:
printf("error\n");
break;
}
```
### default的位置問題
- default可以省略
```
switch (10){
case 1:
printf("玉米炒葡萄1\n");
break;
}
```
- default語句可以寫在switch語句中的任意位置
```
switch (10){
default:
printf("error\n");
break;
case 1:
printf("玉米炒葡萄1\n");
break;
}
```
+ 執行流程:在執行的過程中,如果遇到break語句,則跳出switch語句。如果沒有遇到break 語句,則一直執行到switch語句的結束。
## if和Switch轉換
### if語句和switch語句轉換
- 利用if實現
**問:**
要求用戶輸入一個分數,根據輸入的分數輸出對應的等級
A 90~100 99/10 = 9 90/10= 9 98/10 = 9 100/10 = 10
B 80~89 89/10 = 8
C 70~79
D 60~69
E 0~59
```
// 1.提示用戶輸入學生的分數
printf("請輸入一個0~100的分數\n");
// 2.定義變量保存用戶輸入的分數
int score = -1;
// 3.接收用戶輸入的分數
scanf("%d", &score);
// 4.判斷用戶輸入的分數輸出對應的等級
if (score >= 90 && score <= 100) {
printf("A\n");
}else if (score >= 80 && score <= 89)
{
printf("B\n");
}else if (score >= 70 && score <= 79)
{
printf("C\n");
}else if (score >= 60 && score <= 69)
{
printf("D\n");
}else if (score >= 0 && score <= 59)
{
printf("E\n");
}else{
printf("少喝點三鹿\n");
}
```
- 利用switch實現
```
switch (score/10) {
case 10:
case 9:
printf("A\n");
break;
case 8:
printf("B\n");
break;
case 7:
printf("D\n");
break;
case 6:
printf("C\n");
break;
default:
printf("E\n");
break;
}
```
### if語句和switch語句選擇
- 分支比較多且無法窮盡或進行大量列舉 時最好用if, Switch對遇見判斷非常不利
- 如果數據量不是很大, 并且數據是固定的可以用Switch
- 理論上Switch的效率比if高
- 判斷用戶輸入的數是否大于100:
1. 使用if實現
```
int a = -1;
scanf("%d", &a);
if (a > 100) {
printf("大于\n");
}
```
2. switch實現
```
// 挺(T)萌(M)的(D)搞不定啊
int b = 5;
switch (a) {
case 1:
case 2:
case 3:
case 4:
case 5:
printf("大于\n");
break;
default:
break;
}
```