C語言-選擇結構

簡介

程式在運算過程中需要應付各種狀況,而為了應付各種狀況,C語言提供了條件判斷陳述句

if、else

if條件判斷陳述語法如下:

1
2
3
4
if(條件式)
陳述句1;
else
陳述句2;

這個語法的意思就是如果條件式成立的話,就執行的陳述句1,否則就執行陳述句2

如果想要在條件式不符合的時候不做任何事,可以省略else

如果想要執行的陳述句不只一句,就需要使用成對的大括號將陳述句包起來,例如:

1
2
3
4
5
6
7
8
if(條件式){
陳述句1;
陳述句2;
}
else{
陳述句3;
陳述句4;
}

以下範例程式的作用是判斷整數是否為三的倍數

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
int main(void) {
int input = 0;
int remain = 0;
printf("輸入整數:");
scanf("%d", &input);
remain = input % 3;
if(remain == 0)
printf("%d 為三的倍數\n", input);
else
printf("%d 不是三的倍數\n", input);
return 0;
}

執行結果

輸入整數:5
5 不是三的倍數

在C語言裡面,任何非零的數字都會判斷為True,零才會判斷為False,所以程式可以這樣改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
int main(void) {
int input = 0;
printf("輸入整數:");
scanf("%d", &input);
if(input % 3)
printf("%d 不是三的倍數\n", input);
else
printf("%d 為三的倍數\n", input);
return 0;
}

if陳述句可以判斷多個條件,例如:

1
2
3
4
5
6
7
8
9
10
if(條件1){
陳述句1
}
else
if(條件2){
陳述句2
}
else{
陳述句3
}

但是C語言是格式自由的語言,所以我們可以改成:

1
2
3
4
5
6
7
8
9
if(條件1){
陳述句1
}
else if(條件2){
陳述句2
}
else{
陳述句3
}

這樣比較方便閱讀,以下是多個條件式的範例程式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
int main() {
int score = 0;
printf("輸入分數:");
scanf("%d", &score);
if(score >= 90)
puts("Level : S");
else if(score >= 80 && score < 90)
puts("Level : A");
else if(score >= 70 && score < 80)
puts("Level : B");
else if(score >= 60 && score < 70)
puts("Level : C");
else
puts("Level : D");
return 0;
}

執行結果

輸入分數:100
Level : S

值得注意的是,else的配對是找離它最近的if,所以以下程式碼

1
2
3
4
5
if (條件1)
if(條件2)
陳述句1;
else
陳述句2;

實際上等同於

1
2
3
4
5
6
if (條件1){
if(條件2)
陳述句1;
else
陳述句2;
}

所以括號有加有保佑^.<

switch

switch只能判斷字元或數字,在某些時候比if更具效率跟可讀性,條件判斷的語法如下:

1
2
3
4
5
6
7
8
9
10
switch (變數名稱或運算式) {
case 符合的數字或字元:
陳述句1;
break;
case 符合的數字或字元:
陳述句2;
break;
default:
陳述3;
}

default跟else語句一樣,不一定需要,可以省略。

其中要注意的是符合的數字或字元後面寫的冒號’:’,而不是分號’;’

以下是上面的程式改成switch語法的範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdio.h>
int main() {
int score = 0;
int level = 0;
printf("輸入分數:");
scanf("%d", &score);
level = score / 10;
switch(level) {
case 10:
case 9:
puts("Level : S");
break;
case 8:
puts("Level : A");
break;
case 7:
puts("Level : B");
break;
case 6:
puts("Level : C");
break;
default:
puts("Level : D");
}
return 0;
}

執行結果

輸入分數:89
Level : A

其中陳述句要遇到break才會停止並離開switch,如果忘了加例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
int main() {
int score = 0;
int level = 0;
printf("輸入分數:");
scanf("%d", &score);
level = score / 10;
switch(level) {
case 10:
case 9:
puts("Level : S");
case 8:
puts("Level : A");
case 7:
puts("Level : B");
case 6:
puts("Level : C");
default:
puts("Level : D");
}
return 0;
}

就會得到下列的執行結果

輸入分數:100
Level : S
Level : A
Level : B
Level : C
Level : D

如果是單純比較數字或字元,建議使用switch語法,效率才會被凸顯出來,因為switch只會取出數值一次

但是if卻是每次比較都取出一次,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
switch(ch){
case 'A':
...
break;
case 'B':
...
break;
case 'C':
...
break;
case 'D':
...
break;
case 'E':
...
break;
}

這樣會取出數值一次,比較五次

但是下面這個語法卻是取出數值五次,比較五次

1
2
3
4
5
6
7
8
9
10
if(ch == 'A')
...
else if(ch == 'B')
...
else if(ch == 'C')
...
else if(ch == 'D')
...
else if(ch == 'E')
...

在取出數值的過程中,就可以看到效率明顯的差異

但是switch無法比較複雜語法,算是各有優缺點

另外在gcc的C語言編譯器中提供比較連續數值的語法,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>
int main() {
int score = 0;
printf("輸入分數:");
scanf("%d", &score);
switch(score) {
case 90 ... 100:
puts("Level : S");
break;
case 80 ... 89:
puts("Level : A");
break;
case 70 ... 79:
puts("Level : B");
break;
case 60 ... 69:
puts("Level : C");
break;
default:
puts("Level : D");
}
return 0;
}

執行結果

輸入分數:89
Level : A

條件運算子

條件運算子的語法如下:

1
條件式 ? 成立時的陳述句 : 不成立時的陳述句

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
int main(void) {
int score = 0;
printf("輸入分數:");
scanf("%d", &score);
printf("是否及格?%c\n", (score >= 60 ? 'Y' : 'N'));
return 0;
}

執行結果

輸入分數:60
是否及格?Y

參考

  1. C語言
  2. if 條件判斷
  3. switch 條件判斷
  4. 關係(Relational)運算、條件(Conditional)運算