執行後輸出結果為何?
1 #include <stdio.h>
2 int main(void) {
3 int score = 55;
4 if (score >= 60)
5 printf("PASS\n");
6 else
7 printf("FAIL\n");
8 return 0;
9 }選項 A 正確(★ 本題標準答案)
score=55 未大於等於 60,if 條件為假,執行 else 分支,印出 FAIL。
選項 B 錯誤
score=55 小於 60,if 條件不成立,不會印出 PASS。
選項 C 錯誤
if 與 else 只會擇一執行,不會兩行都印出。
選項 D 錯誤
這是完全合法的 if-else 語法,不會造成編譯錯誤。
關於此程式的執行結果,下列敘述何者正確?
1 #include <stdio.h>
2 int main(void) {
3 int x = 5;
4 if (x > 10)
5 printf("A\n");
6 printf("B\n");
7 return 0;
8 }選項 A 錯誤
縮排在 C 語言中純粹是給人閱讀用的排版,不會決定哪些敘述屬於 if 的範圍;只有緊接在 if 後面的「一行」敘述才受控制。
選項 B 正確(★ 本題標準答案)
沒有加大括號時,if 只會控制緊接在後面的單一敘述(行號5的 printf("A\n"););行號6的 printf("B\n") 已經不屬於 if 的範圍,是不論條件真假都一定會執行的獨立敘述,因此 x=5(條件為假)時只會印出 B。
選項 C 錯誤
行號6的 printf("B\n") 並不受 if 條件控制,即使 x=5 使條件為假,這一行仍然會被執行,因此並非「什麼都不印」。
選項 D 錯誤
if 不加大括號、只控制一行敘述,是完全合法的 C 語法,不會造成編譯錯誤。
執行後輸出結果為何?
1 #include <stdio.h>
2 int main(void) {
3 int score = 60;
4 if (score > 60)
5 printf("優\n");
6 else if (score > 50)
7 printf("甲\n");
8 else
9 printf("乙\n");
10 return 0;
11 }選項 A 錯誤
score=60 並未大於 60(score > 60 為假),所以不會進入第一個分支印出「優」。
選項 B 錯誤
score=60 大於 50,會在第二個條件 score > 50 就成立並印出「甲」,不會走到最後的 else 印出「乙」。
選項 C 正確(★ 本題標準答案)
依序判斷:score>60 為假(60 不大於 60),score>50 為真(60>50),因此印出「甲」。
選項 D 錯誤
if-else if-else 鏈狀結構只會執行其中一個分支,不會三行都印出。
撰寫者原本可能想要先判斷「優異(>=90)」再判斷「及格(>=60)」,但這個程式卻把判斷順序寫反了。請問 score=95 時,此程式實際輸出什麼?為什麼會這樣?
1 #include <stdio.h>
2 int main(void) {
3 int score = 95;
4 if (score >= 60)
5 printf("及格\n");
6 else if (score >= 90)
7 printf("優異\n");
8 else
9 printf("不及格\n");
10 return 0;
11 }選項 A 錯誤
C 語言的 if-else if 鏈狀結構不會自動挑選「最符合」的分支,而是由上而下依序檢查,一旦有條件成立就直接執行該分支,不會考慮後面是否有更精確的條件。
選項 B 錯誤
if-else if-else 鏈狀結構中只會執行其中一個分支,一旦最前面的條件(score>=60)成立,後面的 else if(score>=90)就不會再被檢查,不會依序印出兩行。
選項 C 錯誤
else if 的判斷順序可以自由調整,這是完全合法的語法,只是不同順序可能因為範圍重疊而導致不同的執行結果(如本題所示),不會造成編譯錯誤。
選項 D 正確(★ 本題標準答案)
score=95 讓最前面的 score>=60 就已經成立,因此執行「及格」分支後,後面的 else if (score>=90) 與 else 都會被直接跳過、不再檢查,即使 95 也滿足 >=90,也不會被判斷到,所以只印出「及格」。
關於 C 語言中 if-else if-else 鏈狀結構的敘述,下列何者正確?
選項 A 正確(★ 本題標準答案)
if-else if-else 鏈狀結構由上而下依序檢查,一旦某個條件成立就執行對應分支,並直接跳過後面所有剩餘的 else if 與 else,這些後面的條件根本不會再被檢查(求值)。
選項 B 錯誤
一旦前面已經有條件成立,後面的條件連「求值」都不會發生,並不是「求值但不執行」;這正是第 4 題陷阱的成因。
選項 C 錯誤
else if 可以視需求串接任意多個,沒有數量上限。
選項 D 錯誤
如第 4 題所示,當多個條件的範圍有重疊時,調換判斷順序完全可能改變最終的執行結果。
執行後輸出結果為何?
1 #include <stdio.h>
2 int main(void) {
3 int day = 3;
4 switch (day) {
5 case 1: printf("Mon\n"); break;
6 case 2: printf("Tue\n"); break;
7 case 3: printf("Wed\n"); break;
8 default: printf("Unknown\n");
9 }
10 return 0;
11 }選項 A 錯誤
day=3,並不會比對到 case 1,不會印出 Mon。
選項 B 正確(★ 本題標準答案)
day=3 剛好比對到 case 3,印出 Wed,接著遇到 break 跳出 switch。
選項 C 錯誤
day=3 有比對到 case 3,並不會落到 default 分支。
選項 D 錯誤
switch 比對到某個 case 後,遇到 break 就會跳出,不會把每個 case 都執行過一遍。
關於 C 語言 switch-case 敘述的語法規則,下列何者正確?
選項 A 錯誤
switch 括號內的運算式必須是整數型態,標準 C 語言不允許 switch 直接使用 float 或 double 型態做比對。
選項 B 錯誤
case 標籤的值必須是「編譯時期常數運算式」,不能是一般的變數;把一個變數寫在 case 後面會產生編譯錯誤。
選項 C 正確(★ 本題標準答案)
switch 的控制運算式必須是整數型態(int、char、enum 等),每個 case 標籤的值也必須是編譯時期就能確定的整數常數,這是 switch-case 語法的硬性規定。
選項 D 錯誤
C 語言標準並沒有限制 case 標籤的數量上限,實務上可以依需求撰寫任意多個 case(只受限於編譯器的實作限制,通常遠大於 10)。
執行後會印出幾行?分別是什麼?
1 #include <stdio.h>
2 int main(void) {
3 int month = 2;
4 switch (month) {
5 case 1: printf("Jan\n");
6 case 2: printf("Feb\n");
7 case 3: printf("Mar\n"); break;
8 case 4: printf("Apr\n"); break;
9 default: printf("Other\n");
10 }
11 return 0;
12 }選項 A 錯誤
case 2 之後沒有 break,執行完 Feb 之後會繼續貫穿到 case 3 印出 Mar,不會只印出 1 行。
選項 B 錯誤
month=2 是從 case 2 開始比對進入的,case 1(Jan)不會被執行;貫穿只會往「後面」的 case 繼續,不會回頭執行前面的 case 1。
選項 C 錯誤
Jan 不會被印出,因為程式是直接比對到 case 2 進入的,並不會先經過 case 1。
選項 D 正確(★ 本題標準答案)
month=2 比對到 case 2,印出 Feb 後因為沒有 break 而貫穿到 case 3,印出 Mar,接著遇到 case 3 的 break 才停止,總共印出 2 行;case 1 的內容因為是從 case 2 開始進入,不會被執行到。
撰寫者原本只希望 grade=2 時印出「甲」這一行就好,但實際執行後卻印出了「甲」與「乙」兩行。若只能修改一行程式碼,最適合的修正方式是下列何者?
1 #include <stdio.h>
2 int main(void) {
3 int grade = 2;
4 switch (grade) {
5 case 1:
6 printf("優\n");
7 case 2:
8 printf("甲\n");
9 case 3:
10 printf("乙\n");
11 break;
12 default:
13 printf("未知\n");
14 }
15 return 0;
16 }選項 A 正確(★ 本題標準答案)
在 case 2 自己的程式碼(printf("甲\n");)後面加上 break;,可以讓 grade=2 時執行完「甲」就立刻跳出 switch,不再貫穿到 case 3 印出「乙」,正確解決問題且不影響其他 case。
選項 B 錯誤
刪除行號 11 的 break 只會讓 case 3 之後繼續貫穿到 default,讓問題更嚴重(甚至會多印出「未知」),與目標無關。
選項 C 錯誤
搬動程式碼區塊的位置並不能解決「case 2 沒有 break」這個根本問題,反而會打亂原本的執行順序。
選項 D 錯誤
把 grade 改成 grade+1 會讓比對的數值整個偏移,變成比對 case 3,這樣會改變程式原本的判斷邏輯,並不是針對貫穿問題的正確修法。
關於 switch 敘述中「貫穿(Fall-through)」現象的敘述,下列何者正確?
選項 A 錯誤
貫穿不一定是錯誤,如第 12、13 題所示,刻意讓多個 case 共用同一段程式碼正是善用貫穿特性的常見技巧。
選項 B 正確(★ 本題標準答案)
只要某個 case 的程式碼區塊結尾沒有 break(或 return 等跳出敘述),流程就會自動貫穿到下一個 case 繼續執行,這是 switch 語法本身的正常行為;它可能是忘記加 break 的錯誤(如第 8 題),也可能是刻意共用程式碼的技巧(如第 12 題)。
選項 C 錯誤
任何相鄰的 case 之間,只要前一個沒有 break,都可能發生貫穿,不限於 default 前面的最後一個 case。
選項 D 錯誤
貫穿的效果恰好相反:是繼續往「下一個 case 的程式碼」執行下去,而不是跳出 switch 到後面的敘述。
此程式的 default 標籤被放在 switch 區塊的「開頭」而不是「結尾」。當 x=5 時(沒有任何 case 標籤符合 5),執行後會印出什麼?
1 #include <stdio.h>
2 int main(void) {
3 int x = 5;
4 switch (x) {
5 default:
6 printf("D\n");
7 case 1:
8 printf("1\n");
9 break;
10 case 2:
11 printf("2\n");
12 break;
13 }
14 return 0;
15 }選項 A 錯誤
default 標籤正是設計來處理「沒有任何 case 符合」的情況,x=5 不符合 case 1 或 case 2,因此一定會執行 default 區塊,不會什麼都不印。
選項 B 錯誤
default 本身不會讓 switch 直接結束;如果 default 區塊結尾沒有 break,一樣會貫穿到後面的 case,就像本題一樣。
選項 C 正確(★ 本題標準答案)
x=5 不符合 case 1、case 2,會跳到 default 開始執行,印出 "D";因為 default 區塊沒有 break,會依原始碼中「接下來出現的」case(此處是 case 1)繼續貫穿執行,印出 "1",接著遇到 break 才停止。
選項 D 錯誤
default 是完全會被實際執行的標籤,不是註解;當沒有任何 case 符合時,程式一定會執行到 default 對應的程式碼。
執行後輸出結果為何?
1 #include <stdio.h>
2 int main(void) {
3 char ch = 'e';
4 switch (ch) {
5 case 'a':
6 case 'e':
7 case 'i':
8 case 'o':
9 case 'u':
10 printf("是母音\n");
11 break;
12 default:
13 printf("不是母音\n");
14 }
15 return 0;
16 }選項 A 錯誤
ch='e' 剛好符合 case 'e' 這個標籤,會進入這一組共用程式碼並印出「是母音」,不會走到 default。
選項 B 錯誤
連續堆疊多個 case 標籤(不各自加上程式碼與 break)是完全合法的 C 語法,是刻意善用貫穿特性的常見寫法,不會造成編譯錯誤。
選項 C 錯誤
switch 只會從符合的那一個 case 標籤開始往下執行,並不會把五個 case 都各自比對一次,因此只會印出一次「是母音」,不是五次。
選項 D 正確(★ 本題標準答案)
case 'a' 到 case 'u' 這五個標籤刻意不各自加上程式碼與 break,而是共用寫在最後面(case 'u' 之後)的同一段程式碼;ch='e' 符合其中的 case 'e',因此會執行這段共用程式碼,印出一次「是母音」。
若希望 day 為 6(星期六)或 7(星期日)時,isWeekend 都被設為 1(其餘情況為 0),則行號 6 的【1】最適合填入下列何者?
1 #include <stdio.h>
2 int main(void) {
3 int day = 6;
4 int isWeekend;
5 switch (day) {
6 【1】
7 isWeekend = 1;
8 break;
9 default:
10 isWeekend = 0;
11 }
12 printf("%d\n", isWeekend);
13 return 0;
14 }選項 A 正確(★ 本題標準答案)
C 語言中要讓多個 case 值共用同一段程式碼,標準寫法就是把多個 case 標籤依序堆疊在一起(如 case 6: case 7:),這正是第 12 題示範的貫穿共用技巧。
選項 B 錯誤
`case 6 || case 7:` 不是合法的 C 語法,case 標籤後面只能接編譯時期常數,不能用 || 這種運算子連接兩個 case。
選項 C 錯誤
`case 6, 7:` 也不是合法的 case 標籤語法,C 語言的 switch-case 不支援用逗號在同一個 case 標籤中列出多個數值。
選項 D 錯誤
`or` 不是 C 語言的關鍵字或合法運算子,這種寫法無法通過編譯。
執行後輸出結果為何?
1 #include <stdio.h>
2 enum Color { RED, GREEN, BLUE };
3 int main(void) {
4 enum Color c = GREEN;
5 printf("%d\n", c);
6 return 0;
7 }選項 A 錯誤
0 是 RED 的值,不是 GREEN 的值;enum 成員若都沒有指定初值,會由 0 開始依序遞增。
選項 B 正確(★ 本題標準答案)
enum Color 的成員未指定初值,因此依宣告順序自動編號:RED=0、GREEN=1、BLUE=2,GREEN 對應的整數值是 1。
選項 C 錯誤
2 是 BLUE 的值,不是 GREEN 的值。
選項 D 錯誤
enum 成員在底層是整數常數,%d 只會印出對應的整數值,不會印出成員的名稱字串 "GREEN"。
執行後輸出結果為何?
1 #include <stdio.h>
2 enum Level { LOW = 5, MEDIUM, HIGH = 10, EXTREME };
3 int main(void) {
4 printf("%d %d %d %d\n", LOW, MEDIUM, HIGH, EXTREME);
5 return 0;
6 }選項 A 錯誤
MEDIUM 沒有指定初值,會依「前一個成員的值加 1」計算,得到 6(5+1),但 HIGH 有明確指定為 10,並不會延續 MEDIUM 的自動編號繼續加 1 得到 7;HIGH 之後的 EXTREME 才會延續 HIGH 的值加 1,得到 11,不是 8。
選項 B 錯誤
LOW 已經明確指定初值為 5,不會被重設回 0;MEDIUM 則是延續 LOW 的值加 1,得到 6,不是 1。
選項 C 正確(★ 本題標準答案)
LOW 明確指定為 5;MEDIUM 未指定初值,依規則取「前一個成員的值加 1」,即 5+1=6;HIGH 又明確指定為 10;EXTREME 未指定初值,依規則取「前一個成員的值加 1」,即 10+1=11。四個依序為 5、6、10、11。
選項 D 錯誤
HIGH 已經明確指定初值為 10,不會被額外加 1 變成 11;EXTREME 才是延續 HIGH 的值加 1,得到 11,不是 12。
關於 C 語言 enum(列舉型態)的敘述,下列何者正確?
選項 A 錯誤
enum 成員在底層其實是整數常數,不是字串;如第 14 題所示,用 %d 印出的是對應的整數值,不是名稱字串。
選項 B 錯誤
C 語言並沒有規定 enum 成員的值必須互相唯一,允許多個成員被指定為相同的數值(例如 enum E { A = 1, B = 1 };)。
選項 C 錯誤
如第 15 題所示,未指定初值的成員是依「前一個成員的值加 1」計算,不是永遠固定是 0;只有在沒有任何前面成員被指定初值時,才會從 0 開始。
選項 D 正確(★ 本題標準答案)
enum 本質上就是一組具名的整數常數,編譯器會在背後把每個成員對應到一個整數值,因此才能像一般整數一樣用 %d 印出來,這也是第 14、15 題輸出結果的根本原因。
執行後輸出結果為何?
1 #include <stdio.h>
2 int main(void) {
3 int found = 0;
4 if (!found)
5 printf("Not Found\n");
6 else
7 printf("Found\n");
8 return 0;
9 }選項 A 正確(★ 本題標準答案)
found=0(假),!found 把它反轉成真(1),if 條件成立,印出 Not Found。
選項 B 錯誤
found=0 使 !found 為真,會進入 if 分支印出 Not Found,而不是進入 else 印出 Found。
選項 C 錯誤
if 與 else 只會擇一執行,不會兩行都印出。
選項 D 錯誤
! 是合法的邏輯反向運算子,可以直接用在 int 變數上,不會造成編譯錯誤。
此程式片段執行後會印出「串列是空的,跳過處理」,這個結果是否符合程式碼原本想表達的邏輯?
1 #include <stdio.h>
2 int main(void) {
3 int isEmpty = 1; // 1 表示串列是空的
4 if (!isEmpty)
5 printf("串列有資料,可以繼續處理\n");
6 else
7 printf("串列是空的,跳過處理\n");
8 return 0;
9 }選項 A 錯誤
依照註解,isEmpty=1 代表「串列是空的」,並非有資料,這個選項誤解了變數本身代表的意義。
選項 B 正確(★ 本題標準答案)
isEmpty=1 表示串列是空的;!isEmpty 也就是 !1,結果為假(0),因此執行 else 分支,印出「串列是空的,跳過處理」,這與變數的實際狀態(空的)完全相符,程式邏輯並沒有寫反。
選項 C 錯誤
! 運算子完全可以用在 int 型態的變數上(只要值非 0 視為真,0 視為假),這是非常常見且合法的用法,並不限定只能用於 float。
選項 D 錯誤
本題的判斷完全只依賴 isEmpty 這個旗標變數的值(已知為 1),不需要知道串列實際有幾筆資料,就能確定程式的輸出與邏輯是否一致。
若法律規定「滿 18 歲(含 18 歲)即為成年」,此程式在 age=18 時的判斷結果,下列敘述何者正確?
1 #include <stdio.h>
2 int main(void) {
3 int age = 18;
4 if (age > 18)
5 printf("成年\n");
6 else
7 printf("未成年\n");
8 return 0;
9 }選項 A 錯誤
依題目所述的法律規定,age=18 應該被視為成年,程式卻印出「未成年」,這與規定不符,並非「判斷正確」。
選項 B 錯誤
題目已經明確說明「滿 18 歲(含 18 歲)即為成年」,這個選項與題目給定的規則矛盾。
選項 C 正確(★ 本題標準答案)
題目規定 18 歲本身就算成年,但程式使用 age > 18(不包含 18),導致 age=18 這個邊界值被誤判成「未成年」;只要把比較運算子改成 age >= 18,就能讓 18 歲也被正確判斷為成年,這是典型的比較方向(邊界包含與否)陷阱。
選項 D 錯誤
if 與 else 是互補的兩個分支,一定會執行其中之一並印出對應的文字,並不會什麼都不印出。
在除錯 C 語言的條件判斷邏輯時,關於 !flag(邏輯反向)與比較運算子方向(如 >、>=、<、<=)的敘述,下列何者正確?
選項 A 錯誤
如第 18 題所示,!flag 本身不一定是錯誤,關鍵在於它的意義是否與變數命名所代表的邏輯相符,需要實際追蹤而不是一律避免使用。
選項 B 錯誤
如第 19 題所示,`>` 與 `>=` 在邊界值(例如剛好等於門檻的那個值)上會產生截然不同的判斷結果,不能隨意互換。
選項 C 錯誤
程式能通過編譯只代表語法正確,不代表邏輯正確;第 4、19 題中的程式都能正常編譯執行,但邏輯上仍然有問題。
選項 D 正確(★ 本題標準答案)
編譯成功只保證語法沒有錯誤,無法保證邏輯正確;針對邊界值實際代入追蹤,以及確認 !flag 的意義是否與變數命名相符,都是找出邏輯錯誤的關鍵做法,而這些都不是編譯器單靠語法檢查就能發現的。