統測資電類・資訊科專業科目(二)核心考點

第 4 章:選擇結構(if/switch/enum)

本章統整統測程式設計中「分支邏輯」的三大工具:if / if-else if、switch-case 與 enum(111~115 年共計 5 題考古真題)。 出題老師最愛把「邊界值 >= 與 >」、「switch 貫穿 fall-through」、「enum 自動編號規則」與「邏輯旗標方向除錯」揉合在一起設計陷阱。 本教學將帶你掌握清晰的分支流程圖、貫穿追蹤技巧,並透過5 題真題 + 5 題模擬題的所有選項深度剖析,徹底掃除所有答題盲點!

🔀
7 大核心
選擇結構觀念全解構
🎯
5 題真題
111~115 統測題全收錄
💡
全選項剖析
A/B/C/D 逐項深入拆解
🚀
100% 互動
點擊即答 + 展開詳解

1 if/if-else 基礎與分支流程判斷

if 就像十字路口的紅綠燈:程式跑到這裡,會先檢查條件式的真假——條件成立(非0,也就是「真」)就走進 if 那個路口;不成立(0,也就是「假」)就直接跳過,改走 else 那條路(若沒寫 else,不成立時就什麼都不做,繼續往下一行執行)。

語法形式行為白話比喻
if(條件) A; 條件為真才執行 A,為假就直接跳過整個 if,不做任何事。 紅燈才停車,綠燈直接通過,路口沒有第二個選擇。
if(條件) A; else B; 條件為真執行 A;為假執行 B。兩者必擇一,不會都做也不會都不做。 路口只有兩條路,紅燈往左,綠燈往右,一定會走其中一條。
C Code:if-else 基礎示範
#include <stdio.h>
int main(void) {
    int temperature = 28;
    if (temperature >= 30) {
        printf("好熱,開冷氣!\n");
    } else {
        printf("還算舒適。\n");
    }
    return 0;
}
🖥️ 終端機執行輸出結果
還算舒適。
⚠️ 新手必踩陷阱:把「比較 ==」誤寫成「賦值 =」

if (flag = 0) 是合法的 C 語法,但它的意思是「把 0 賦值給 flag,再拿賦值後的結果(0,也就是假)當作條件」——並不是在比較 flag 是否等於 0!
這種寫法幾乎每次都是手誤,因為它會讓 if 恆為某個固定值,完全喪失「依變數當下狀態做判斷」的意義。統測常用這個陷阱測驗學生是否真正理解「賦值」與「比較」是兩回事。

2 if-else if 鏈狀結構與邊界值陷阱

當條件不只兩種,而是要分成好幾個等級時,就要用 if-else if-else 鏈狀結構。它的執行方式像「瀑布式關卡」:程式由上往下逐一檢查,只要遇到第一個成立的條件,就執行對應的程式碼並直接跳出整條鏈,後面的條件完全不會再被檢查,即使它們理論上也成立。

💡 白話比喻:分級瀑布關卡

想像成績分級系統像一連串的瀑布關卡:先問「有沒有超過90?」——過了就直接掉進「A級」的水潭,不會再往下掉去檢查「有沒有超過80」。只有沒過90的人,才會繼續往下一關「有沒有超過80?」检查。順序很重要:條件的撰寫順序若顛倒,會讓某些等級永遠不可能被判斷到。

C Code:if-else if 鏈狀結構與邊界值
#include <stdio.h>
int main(void) {
    int score = 60;
    if (score >= 90)      printf("A\n");
    else if (score >= 80) printf("B\n");
    else if (score >= 60) printf("C\n"); // 60剛好落在這一段
    else                  printf("F\n");
    return 0;
}
🖥️ 終端機執行輸出結果
C
⚠️ 統測最愛陷阱:邊界值該用 >= 還是 >?

score >= 60(大於等於,包含60分本身)跟 score > 60(嚴格大於,不含60分)在「剛好等於邊界值」時會產生完全不同的結果!統測經常把邊界值設計成剛好卡在條件上,就是要看你有沒有注意到 >= 與 > 只差一個等號、行為卻天差地遠。做這類題目時,請務必把「邊界值本身」代入程式碼手動推演一次。

寫法score = 60 時是否成立score = 59 時是否成立
score >= 60✅ 成立(60也算)❌ 不成立
score > 60❌ 不成立(60不算,要嚴格大於)❌ 不成立

3 switch-case 語法結構與執行流程

當同一個變數要對應「很多種固定數值」的分支時,一長串 if-else if 會顯得又臭又長;這時可以改用 switch-case,它就像捷運站的月台指標——依照手中車票(switch的判斷值)上寫的號碼,直接跳到對應的月台(case),不需要像 if-else if 那樣一關一關檢查過去。

比較項目if-else if 鏈switch-case
適合場景 條件是「範圍區間」(如 score >= 60)或多個不同變數的邏輯組合 條件是「單一變數」對應「多個固定離散值」(如 day == 1, 2, 3...)
判斷方式 由上而下逐條檢查,第一個成立就執行並結束 直接依數值或字元跳到對應 case 進入點
結束機制 條件成立後自動結束整條鏈 不會自動結束,必須明確寫 break; 才會跳出
C Code:switch-case 標準寫法(含 break)
#include <stdio.h>
int main(void) {
    int day = 3;
    switch (day) {
        case 1: case 2: case 3: case 4: case 5:
            printf("平日\n");
            break;
        case 6: case 7:
            printf("假日\n");
            break;
        default:
            printf("不合法的輸入\n");
    }
    return 0;
}
🖥️ 終端機執行輸出結果
平日
💡 switch 語法三個規則

1. switch() 括號內的判斷值只能是整數或字元(int、char、enum 等),不能是浮點數或字串。
2. 每個 case 常數值: 後面接的是「進入點」,不是條件式,常數值必須是編譯時期已知的固定值。
3. default: 是「以上皆非」的收尾分支,可放在任何位置(雖然習慣上放最後),沒有比對到任何 case 時就會執行它。

4 switch 貫穿(Fall-through)陷阱全解析 — 統測最愛的坑

這是本章統測命中率最高的觀念!C 語言的 switch 一旦進入某個 case,就會像忘記剎車的溜滑梯一樣,一路往下貫穿執行後面所有的敘述,直到遇到 break; 或整個 switch 區塊結束為止——完全不會理會後面 case 標籤寫的是什麼數字,因為那些數字在貫穿時只是「路過的地標」,不會被重新拿來比對判斷值。

C Code:忘記寫 break 的貫穿效應
#include <stdio.h>
int main(void) {
    int i = 2;
    switch (i) {
        case 1: printf("A"); break;
        case 2: printf("B");        // 沒有break!
        case 3: printf("C"); break; // 會被貫穿執行
        default: printf("D");
    }
    return 0;
}
🖥️ 終端機執行輸出結果
BC
⚠️ 逐步拆解:為什麼是「BC」而不是「B」?

1. i = 2,switch 直接跳進 case 2: 這個進入點,印出 B。
2. case 2 這一行的結尾沒有 break;,所以程式並不會離開 switch,而是直接往下一行執行,剛好下一行是 case 3: 底下的程式碼,於是印出 C。
3. case 3 這次有寫 break;,程式才真正跳出 switch,default 完全不會執行到。
最終輸出為 "BC"。這正是「貫穿」——不是 bug,是 C 語言 switch 天生的行為,寫程式時若不想要這個效果,就必須每個 case 都手動加上 break。

🧠 記憶口訣

「沒 break 不停,一路溜到底」——只要沒看到 break;,就假設程式會一直往下執行,不管中間路過幾個 case 標籤,直到真的遇到 break 或整個 switch 的右大括號 } 為止。

5 多重 case 共用程式碼技巧(有意貫穿)

貫穿並非總是「忘記寫 break」的錯誤,它也可以是刻意設計的技巧:當好幾個不同的 case 值都要執行「完全相同」的一段程式碼時,可以把這些 case 標籤緊鄰疊在一起、共用最後那一段程式碼,就像好幾個不同門牌號碼共用同一個信箱一樣。

C Code:多重 case 疊加(本章開頭例②)
#include <stdio.h>
int main(void) {
    int day = 3;
    switch (day) {
        case 1: case 2: case 3: case 4: case 5:
            printf("平日\n");
            break;
        case 6: case 7:
            printf("假日\n");
            break;
        default:
            printf("不合法的輸入\n");
    }
    return 0;
}

case 1: case 2: case 3: case 4: case 5: 這五行中間都沒有任何程式碼或 break,所以無論 day 是 1、2、3、4 還是 5,都會一路貫穿到最後才共同執行 printf("平日\n"); break;。這是「有意貫穿」——利用貫穿特性省去重複撰寫五次一模一樣的程式碼。

💡 如何分辨「有意貫穿」與「無意貫穿(忘記break)」?

關鍵在於兩個 case 之間有沒有夾著程式碼:
• 如果兩個 case 標籤緊鄰、中間完全沒有程式碼(如 case 1: case 2:),這是刻意設計的「分組」,讓多個值共用同一段邏輯。
• 如果 case 標籤中間夾著一段 printf 或其他敘述、卻沒接 break(如本章第4節的 case 2: printf("B"); 沒接 break 就換行到 case 3),這通常代表「忘記寫 break」,會造成非預期的貫穿。統測最愛在這種地方出題考細心程度!

6 enum 列舉型態:自動編號與指定初值規則

enum(列舉)可以把一組有意義的具名常數包裝成一個新型態,讓程式碼用 Run、Stop 這種有意義的名字取代難以理解的數字 1、2、3。它的編號規則就像停車場的樓層自動編號機:預設從 0 開始,每往下一個成員就自動 +1;如果中途有人手動指定了某個樓層數字,編號機就會從那個數字繼續往下遞增。

enum 成員規則範例值
沒有指定初值的第一個成員 預設從 0 開始 enum{A}; → A=0
沒有指定初值的後續成員 等於「前一個成員的值 + 1」 enum{A,B}; → A=0, B=1
有明確指定初值的成員 直接採用指定的數字,不受前面成員影響 enum{A,B=10}; → A=0, B=10
指定初值之後、又沒指定的成員 接續「剛剛指定的那個值 + 1」繼續遞增 enum{A,B=10,C}; → A=0, B=10, C=11
C Code:混合指定初值與自動遞增
enum State { Run = 1, Stop, Pause = 3, Exit };
// Run=1(明確指定)
// Stop=2(接續Run+1,自動遞增)
// Pause=3(明確指定,重新設定)
// Exit=4(接續Pause+1,自動遞增)

int main(void) {
    enum State current = Stop;
    printf("%d\n", current); // 輸出 2
    return 0;
}
🖥️ 終端機執行輸出結果
2
⚠️ 常見誤解:以為每個「沒指定值」的成員都重新從 0 算起

很多人誤以為 Pause = 3 之後的 Exit(沒指定值)會「重新從0開始編號」,但其實規則永遠是「沿用前一個成員的值 + 1」,不管前一個成員是自動遞增出來的,還是被明確指定的。所以 Exit 一定是 Pause + 1 = 4,不會是別的數字。

7 條件判斷邏輯除錯:!flag 與比較方向陷阱

統測很喜歡出「這段程式碼邏輯寫反了,請問怎麼修改」這類除錯題。最常見的手法是先用一個 flag(布林旗標)變數記錄某個條件的真假,再用 !flag(邏輯 NOT,反相)去判斷分支——如果條件判斷式的比較方向從一開始就寫反了,後面即使 !flag 的用法完全正確,結果還是會整個顛倒,就像接反的電燈開關:開關本身沒壞,但因為線路接反,「開」反而變成「關」。

C Code:比較方向寫反的邏輯除錯題
int flag = -1;
int x = 17;    // x 表示完成的題目數
int y = 18;    // y 表示完成的題目數
flag = (int)(x + y < 32);
if (!flag)
    printf("Go! 繼續努力!\n");
else
    printf("Ya! 快完成了!\n");
// 需求:總和少於32要顯示「Go!」,否則顯示「Ya!」
⚠️ 逐步除錯:flag 的意義被寫反了

1. x + y = 35,實際上已經達標(≥32),理應顯示「Ya! 快完成了!」。
2. 但程式算出 flag = (35 < 32) = 0,接著 !flag = !0 = 1(真),反而執行了 if 分支印出「Go!」——結果完全顛倒!
3. 問題出在 flag 一開始被設計成「還沒達標」的旗標(x+y < 32),但後面卻用 !flag 判斷「已完成」,語意對不上。
4. 正確修法:把比較方向反過來,讓 flag = (x+y >= 32) 直接代表「已達標」,這樣 !flag 才能正確對應「還沒達標,要顯示Go!」的原始需求。

💡 除錯技巧:先確認「旗標的語意」,再檢查「用法是否呼應語意」

遇到這類題目,不要急著檢查 !、==、&& 這些運算子寫得對不對,先問自己:「這個 flag 變數,設計者原本想讓它代表什麼意思?」再檢查後面所有用到它的地方,是否都跟這個語意一致。本題的 bug 不在 !flag 這個用法本身(用法完全正確),而在比較方向——這是統測除錯題最容易忽略的盲點。

8 111~115 歷屆統測真題全選項深度剖析(共 5 題)

以下收錄統測專業科目(二)近年全部 5 題選擇結構(if/switch/enum)真題。每題均提供高解析度原始考題掃描圖、互動選項按鈕與所有選項逐項深入解析:

111 統測專二 Q42 📌 概念:選擇結構 if-else if 鏈與邊界值判斷
試題來源:技專校院入學測驗中心
下列 C 語言程式碼片段執行後,變數 y 的值為何?
題幹程式碼
int y, a=45;
if(a>=60)
    y=a+1;
else if(a>=50)
    y=a+2;
else
    y=a+3;
111 統測專二 Q42 題目截圖
本題標準答案: (D) 48

🔍 四個選項逐項深度剖析

選項 A(45)錯誤解析
此答案誤以為當 if 與 else if 兩個條件都不成立時,y 會保持原本的 a 值不變、什麼都不做。但這段程式碼有一個「裸 else」(沒有條件、必定執行的最後分支),只要前面兩個條件都不成立,程式就一定會執行 y=a+3;,y 絕不會維持在 45 沒被賦值。
選項 B(46)錯誤解析
此答案對應 y=a+1,也就是誤判 a>=60 這個條件成立了。但 a=45,45 並沒有大於等於 60,第一個 if 條件應為假,不會進入這個分支。
選項 C(47)錯誤解析
此答案對應 y=a+2,也就是誤判 a>=50 這個條件成立了。但 a=45,45 同樣沒有大於等於 50,第二個 else if 條件也應為假,容易被「45很接近50」的直覺誤導而選錯。
正確答案完整推導(★ 本題標準答案)
a=45:第一個條件 a>=60 → 45>=60 為假;第二個條件 a>=50 → 45>=50 也為假;兩者皆不成立,程式落入最後的裸 else 分支,執行 y=a+3=45+3=48。故選 (D)。
113 統測專二 Q39 📌 概念:switch-case 貫穿/位元運算/字元運算複合陷阱
試題來源:技專校院入學測驗中心
下列 C 語言程式,當程式執行完畢後,輸出為何?
題幹程式碼
#include <stdio.h>
int main(){
    unsigned char i=3;
    switch ( (i&0x0e) % 5){
      case(1):
            printf("%c", '0'+i);
            break;
      case(2):
            printf("%c", '0'+i*i);
      case(3):
            printf("%c", 'a'+i*i);
      default:
            printf("%c", 'z');
    }
    return(0);
}
113 統測專二 Q39 題目截圖
本題標準答案: (A) 9jz

🔍 四個選項逐項深度剖析

正確答案完整推導(★ 本題標準答案)
i=3 的二進位為 00000011。i & 0x0e(0x0e=00001110)逐位元 AND 得 00000010=2;2 % 5 = 2,switch 跳進 case(2):印出 '0'+i*i = '0'+9 = '9'(ASCII加法,'0'是48,48+9=57='9')。case(2) 結尾沒有 break,貫穿進入 case(3):印出 'a'+i*i = 'a'+9 = 'j'('a'是97,97+9=106='j')。case(3) 同樣沒有 break,再貫穿進入 default:印出 'z'。三段合計輸出 “9jz”,選 (A)。
選項 B(927z)錯誤解析
這類答案通常來自在手動追蹤「貫穿執行」時,把 case(2) 與 case(3) 兩段 printf 的 ASCII 換算過程算錯或重複套用,多印出了額外的數字字元。核心觀念沒抓穩:貫穿只是「照抄後面的程式碼繼續執行」,不會重新計算或疊加任何中間值。
選項 C(9270)錯誤解析
這類答案的常見成因,是把某一步該輸出的字元誤植成它對應的數字(例如該印出字元 'j' 時卻印出了對應的十進位數字)。這反映對 %c 格式化語意不熟——%c 是把運算結果的整數值當作 ASCII 碼、對照輸出對應的「字元」,而不是直接把運算後的整數值印出來。
選項 D(9)錯誤解析
這是本題最具誘答力的錯誤答案,反映的是「誤以為 C 語言的 switch 每個 case 執行完會像某些語言一樣自動跳出」的常見迷思。事實上 case(2) 結尾完全沒有寫 break;,程式一定會貫穿到 case(3)、default 繼續執行,並不會只印出 case(2) 的內容「9」就結束。
113 統測專二 Q40 📌 概念:enum 列舉型態/多重 if 條件連鎖判斷
試題來源:技專校院入學測驗中心
程式執行到最後,下列敘述何者正確?
題幹程式碼
enum States { Run = 1, Stop, Pause = 3, Exit };
States StateMachine = Pause;
int Command = 0;
std::cin >> Command;
if (Command == 1) StateMachine = Stop;
if (Command == 2 && StateMachine == Pause)
    StateMachine = Run;
if (Command == 3 || StateMachine == Stop)
    StateMachine = Exit;
113 統測專二 Q40 題目截圖
本題標準答案: (A) 當 Command 為 1,StateMachine 的值為 Exit

🔍 四個選項逐項深度剖析

正確答案完整推導(★ 本題標準答案)
enum 編號:Run=1, Stop=2, Pause=3, Exit=4。初始 StateMachine=Pause(3),Command=1。第一個 if:Command==1 為真 → StateMachine 變為 Stop(2)。第二個 if:Command==2 為假 → 跳過。第三個 if:Command==3 為假,但 StateMachine==Stop(此刻已是2)為真,|| 只要有一邊真就成立 → StateMachine 變為 Exit(4)。最終為 Exit,選 (A)。
選項 B 錯誤解析
當 Command=2 時:第二個 if 的 Command==2 && StateMachine==Pause 兩邊皆為真(StateMachine 此時仍是初始值 Pause),條件成立,會確實執行 StateMachine = Run;。此選項誤以為 if 只是「檢查」條件是否成立、卻忽略了 if 本體真的會執行賦值敘述,把 StateMachine 從 Pause 改成了 Run,因此最終值應為 Run(1) 而非 Pause(3)。
選項 C 錯誤解析
當 Command=3 時:第三個 if 的 Command==3 || StateMachine==Stop 中,Command==3 本身就已為真,依 || 邏輯或的短路特性,整個條件即成立,執行 StateMachine = Exit;。此選項很可能來自把條件式中的比較運算子 == 誤讀成賦值運算子 =,誤以為 StateMachine==Stop 這段是「把 StateMachine 設為 Stop」;但它其實只是比較,真正造成改變的是 if 外層的 StateMachine = Exit;,最終應為 Exit 而非 Stop。
選項 D 錯誤解析
當 Command=4 時:三個 if 的 Command==1/2/3 全部為假,且 StateMachine 從未被改變過(仍是初始值 Pause,不等於 Stop),第三個 if 的 StateMachine==Stop 也為假,三個條件全部不成立。此選項誤以為當 Command 不符合任何專屬條件時,StateMachine 會被重置為某個預設值 Run,但事實上三個 if 都沒有成立,StateMachine 應該維持一開始的初值 Pause,並不會自動變成 Run。
114 統測專二 Q38 📌 概念:關係運算子方向與邏輯旗標(flag)除錯
試題來源:技專校院入學測驗中心
完成題目數總和少於32題要顯示「Go!繼續努力!」,否則顯示「Ya!快完成了!」,下列程式應如何修改才能顯示正確訊息?
題幹程式碼
int flag = -1;
int x = 17;    // x 表示小明完成的題目數
int y = 18;    // y 表示小玲完成的題目數
flag = (int)(x+y < 32);
if (!flag)
  printf("「Go!繼續努力!」");
else
  printf("「Ya!快完成了!」");
114 統測專二 Q38 題目截圖
本題標準答案: (C) 行號6的 x+y < 32 改為 x+y >= 32

🔍 四個選項逐項深度剖析

選項 A 錯誤解析
把宣告的資料型態從 int 改成 float,並不會改變 x+y < 32 這個關係運算式的比較方向與真假結果——不論是整數或浮點數,35 都不小於 32,比較結果依然相同。這個選項誤以為問題出在資料型態的精度或轉型上,卻沒發現真正的問題是條件判斷的方向從一開始就寫反了。
選項 B 錯誤解析
把 if(!flag) 改成 if(flag = 32) 會把「邏輯判斷」偷換成「賦值運算式」:flag = 32 這個運算式的值恆為 32(非0,也就是恆為真),會讓 if 分支永遠被執行,不管 x+y 的總和究竟是多少,都只會印出「Go!」。這正是混淆「賦值運算子 =」與「邏輯判斷」差異的典型錯誤,完全無法依總和正確反映對應訊息。
正確答案完整推導(★ 本題標準答案)
x+y=35,已經達標(≥32),理應顯示「Ya!快完成了!」,但原程式 flag=(35<32)=0,!flag=!0=1(真)反而執行了 if 分支印出「Go!」,邏輯完全顛倒。把第6行改成 x+y >= 32 後,flag 直接代表「總和已達標」:達標時 flag=1、!flag=0 走 else 印出「Ya!」;未達標時 flag=0、!flag=1 走 if 印出「Go!」,兩種情況都正確對應需求,選 (C)。
選項 D 錯誤解析
flag 的初始值 -1 在第4行就已經被 flag = (int)(x+y < 32); 這行運算結果重新覆蓋,在後續的 if 判斷中根本用不到初始值。這個選項誤以為 flag 的「初始值」在後續判斷中仍有作用,忽略了它早就被新的運算結果取代,改成 1 對最終輸出結果完全沒有任何影響。
115 統測專二 Q42 📌 概念:switch-case 選擇結構/字串走訪計數/缺漏 case 陷阱
試題來源:技專校院入學測驗中心
下列 C 語言程式執行後的輸出結果為何?
題幹程式碼
char String[16]="A1(2ABC*.BAA3CB";
int i=0, c_A=0, c_B=0, c_C=0, c_digi=0, c_sym=0;
while(String[i] != '\0'){
  switch(String[i]){
    case 'A':
        c_A++;  break;
    case 'B':
        c_B++;  break;
    case '1': case '2': case '3':
        c_digi++;  break;
    default:
        c_sym++;
  }
  i++;
}
printf("%d,%d,%d,%d,%d",c_A,c_B,c_C,c_digi,c_sym);
115 統測專二 Q42 題目截圖
本題標準答案: (B) 4,3,0,3,5

🔍 四個選項逐項深度剖析

選項 A(4,3,2,3,3)錯誤解析
此答案誤以為程式中真的有幫 'C' 字元寫了對應的 case 'C': 分支,因而把字串中的 2 個 'C' 算進了 c_C,卻沒發現這 2 個 'C' 因為找不到任何 case 相符(程式碼完全沒有 case 'C':),實際上會落入 default,應該被計入 c_sym 而不是 c_C。
正確答案完整推導(★ 本題標準答案)
逐字元走訪 "A1(2ABC*.BAA3CB":A 出現 4 次(c_A=4);B 出現 3 次(c_B=3);數字 '1'、'2'、'3' 共出現 3 次(c_digi=3);程式碼沒有 case 'C':,所以 c_C 恆為 0;剩下落入 default 的字元包含真正的符號「(、*、.」共3個,加上沒有對應 case 的 2 個 'C' 字元,c_sym = 3+2 = 5。最終輸出 4,3,0,3,5,選 (B)。
選項 C(4,3,0,3,3)錯誤解析
此答案正確判斷出「沒有 case 'C',所以 c_C=0」,但在計算 c_sym 時只算出了真正的符號字元「(、*、.」共3個,卻忘記字元 'C' 同樣因為沒有對應的 case,也會貫穿落入 default,必須一併計入 c_sym,導致漏算了字串中的 2 個 'C'。
選項 D(4,3,3,3,2)錯誤解析
此答案把「落入 default 的字元」正確算出了總數(2個'C' + 3個真符號),但誤把這兩類數量分別填錯了欄位——3 這個數字被誤放進了 c_C 欄位,2 這個數字被誤放進了 c_sym 欄位,正好與正確答案相反。核心問題在於忽略了程式碼中 c_C 這個變數從頭到尾都沒有被遞增過(因為沒有對應的 case 分支),理應恆為 0。

9 高職段考與模擬精選實戰題(5 題全選項解析)

透過以下 5 題精選模擬試題,全面檢驗你對邊界值判斷、switch 貫穿、enum 編號規則與邏輯除錯的掌握度:

模擬實戰第 1 題 📌 概念:if-else if 鏈狀結構與邊界值(> 與 >= 的差異)
已知下列 C 語言程式碼片段,變數 score 的值為 70,執行後 grade 的值為何?
C Code
int score = 70, grade;
if (score > 90) grade = 5;
else if (score > 80) grade = 4;
else if (score > 70) grade = 3;
else if (score > 60) grade = 2;
else grade = 1;
本題標準答案: (D) 2

🔍 四個選項逐項深度剖析

選項 A 錯誤解析
此答案未依程式碼逐行檢查比較運算,只是憑直覺覺得「70分應該算不錯」就選了最高等第。實際上第一個條件 score > 90(70>90)明顯為假,不會進入這個分支。
選項 B 錯誤解析
此答案對應 score > 80 成立,但 70 並不大於 80,這個條件應為假。容易發生在快速瀏覽數字、沒有真的把 70 代入每一行比較運算的情況。
選項 C 錯誤解析
此答案要求 score > 70 成立,但這裡用的是嚴格大於,70 並不大於 70 本身(70>70 為假)!這正是把 > 誤看成 >= 的典型邊界值陷阱——70 剛好卡在邊界上,若忽略「嚴格大於」這個細節,就會誤以為條件成立。
正確答案完整推導(★ 本題標準答案)
依序檢查:70>90 假;70>80 假;70>70 假(70不嚴格大於70);70>60 為真 → 進入這個分支,grade=2。故選 (D)。
模擬實戰第 2 題 📌 概念:switch 搭配整數除法與多重 case 分組(貫穿)
已知下列 C 語言程式碼片段,變數 score 的值為 75,執行後印出的 grade 值為何?
C Code
int score = 75, grade = 0;
switch (score / 10) {
    case 10:
    case 9: grade = 1; break;
    case 8: grade = 2; break;
    case 7:
    case 6: grade = 3; break;
    default: grade = 4;
}
printf("%d", grade);
本題標準答案: (C) 3

🔍 四個選項逐項深度剖析

選項 A 錯誤解析
要得到這個結果,score/10 必須等於 10 或 9。此答案可能誤把 75/10 用四捨五入算成接近 8 或以上的整數,卻忽略了 C 語言的整數除法會直接捨去小數位(無條件捨去),75/10 的正確結果是 7,不是 9 或 10。
選項 B 錯誤解析
要得到這個結果,score/10 必須等於 8,對應「80多分」的級距。此答案可能誤以為 75 分屬於 80 分級距,但 75/10 用整數除法算出來就是 7(捨去 0.5),並非 8。
正確答案完整推導(★ 本題標準答案)
score/10 為整數除法,75/10=7(捨去小數)。switch 跳進 case 7:,這一行中間沒有任何程式碼與 break,直接貫穿到 case 6: 底下的 grade=3; break;,執行後 grade=3,印出 3,選 (C)。
選項 D 錯誤解析
此答案誤以為 75/10=7 這個值找不到任何相符的 case(因為只看到單獨的 case 7: 沒有直接接程式碼),因而預期會落入 default。但其實 case 7: 透過「貫穿」與 case 6: 共用了同一段程式碼,並不會跳到 default——只要 case 標籤本身數值相符,就一定會從那個進入點開始執行,不管它自己底下有沒有直接接程式碼。
模擬實戰第 3 題 📌 概念:enum 混合指定初值與自動遞增規則
已知下列 enum 宣告與程式碼片段,執行後 total 的值為何?
C Code
enum Level { Bronze, Silver = 5, Gold, Platinum = 10, Diamond };
int total = Gold + Diamond;
printf("%d", total);
本題標準答案: (C) 17

🔍 四個選項逐項深度剖析

選項 A(12)錯誤解析
此答案很可能把 Gold 誤算成 1(總和 1+11=12),誤以為「沒有明確指定初值」的成員會重新從 0 開始逐一編號。但正確規則是「沒指定值的成員 = 前一個成員的值 + 1」,Gold 緊接在 Silver=5 之後,所以 Gold=5+1=6,並不是脫離前文、重新從0算起的1。
選項 B(13)錯誤解析
此答案把 Diamond 誤算成 7(總和 6+7=13),誤以為 Diamond 是緊接著 Gold(6) 以「+1」往下算的(6+1=7),忽略了中間的 Platinum = 10 已經明確重新指定了初值。Diamond 其實是接在 Platinum 之後,等於 Platinum+1=11,而不是無視 Platinum、直接沿用 Gold 繼續累加。
正確答案完整推導(★ 本題標準答案)
逐一推算:Bronze=0(預設起始);Silver=5(明確指定);Gold=Silver+1=6(自動遞增);Platinum=10(明確指定,重新設定);Diamond=Platinum+1=11(自動遞增)。所以 total = Gold + Diamond = 6 + 11 = 17,選 (C)。
選項 D(22)錯誤解析
此答案把 Gold 誤算成 11(與 Diamond 同值,總和 11+11=22),可能誤以為 Gold 和 Diamond 這兩個「沒有指定初值」的成員,都會直接取用整個 enum 裡最近一次明確指定的數字。但正確規則是接續「緊鄰的前一個成員」逐一遞增,Gold 只會參考 Silver(5+1=6),並不會跳過 Silver、直接參考後面才出現的 Platinum。
模擬實戰第 4 題 📌 概念:賦值運算子 = 誤用於條件式中的經典陷阱
已知下列 C 語言程式碼片段(flag 初始值為 0),執行後的結果為何?
C Code
int flag = 0;
if (flag = 5) {
    printf("A");
} else {
    printf("B");
}
printf("\nflag = %d", flag);
本題標準答案: (A) 印出 A,且 flag 最終為 5

🔍 四個選項逐項深度剖析

正確答案完整推導(★ 本題標準答案)
flag = 5 是完全合法的 C 語言運算式:它會把 5 賦值給 flag,而且整個賦值運算式本身的「值」就等於 5(非0,也就是真)。因此 if(flag = 5) 條件成立,執行 if 分支印出 A;同時這個賦值也是真的執行過的敘述,flag 最終確實變成 5。
選項 B 錯誤解析
此答案誤把 if(flag = 5) 看成是在「比較」flag 是否等於 5(誤讀成 flag == 5)。因為 flag 原本是 0,若真的用 == 比較,0==5 為假,才會誤判跳到 else 印出 B。但 C 語言允許把「賦值運算式」直接當作 if 的條件式,這裡是先賦值、再拿賦值後的結果做真假判斷,並不是比較。
選項 C 錯誤解析
此答案誤以為「在條件式中直接賦值」這種寫法不合法(像某些較嚴格語言會禁止或報錯)。但 C 語言完全允許將賦值運算式當作條件式使用——雖然這種寫法容易造成邏輯錯誤,某些編譯器可能會給出警告,但它不是編譯錯誤,程式可以正常編譯並執行。
選項 D 錯誤解析
此答案正確判斷出會印出「A」(因為賦值後的值5為真),卻誤以為賦值只在條件判斷「當下」暫時借用、不會真的改變原本的變數。但事實上 flag = 5 這個賦值敘述本身就會確實地把 flag 的值永久改成 5,並不是條件判斷結束後就恢復原狀,程式最後印出的 flag 值就是 5。
模擬實戰第 5 題 📌 概念:switch 貫穿路徑追蹤:break 出現位置的影響
已知下列 C 語言程式碼片段,變數 n 的值為 2,執行後的輸出結果為何?
C Code
#include <stdio.h>
int main(void) {
    int n = 2;
    switch (n) {
        case 1:
            printf("one");
        case 2:
            printf("two");
        case 3:
            printf("three");
            break;
        case 4:
            printf("four");
        default:
            printf("other");
    }
    return 0;
}
本題標準答案: (B) twothree

🔍 四個選項逐項深度剖析

選項 A(two)錯誤解析
此答案誤以為每個 case 執行完畢後會像某些語言一樣自動結束 switch。但 case 2: 這一行結尾完全沒有寫 break;,程式會繼續往下貫穿執行,並不會只印出「two」就停止。
正確答案完整推導(★ 本題標準答案)
n=2,switch 直接跳進 case 2:,印出 “two”。這一行結尾沒有 break,貫穿進入 case 3:,印出 “three”;case 3 這裡有寫 break;,程式立刻跳出整個 switch,case 4 與 default 完全不會執行。最終輸出 “twothree”,選 (B)。
選項 C(twothreefour)錯誤解析
此答案誤以為 case 3 結尾的 break; 不會生效、或不小心看漏了它的存在,以為程式會繼續貫穿到 case 4。但 case 3 結尾確實寫了 break,程式在印出 "three" 之後就會真正跳出 switch,不會再執行 case 4 的程式碼。
選項 D(twothreefourother)錯誤解析
此答案誤以為程式會貫穿執行完 switch 裡的所有 case(包含 default)才會結束,完全忽略了 case 3 後面確實寫了 break。這是對「貫穿」特性過度延伸的常見誤解——貫穿只發生在「沒有 break」的地方,一旦程式遇到 break,就會立刻結束整個 switch,不會繼續往後執行任何 case。

10 考前衝刺 10 秒速記口訣 & 核心知識檢核清單

✅
if-else if 由上而下
第一個成立的條件就執行並跳出整條鏈,後面條件即使也成立也不會再檢查。
✅
邊界值口訣
>= 含邊界本身;> 不含邊界,剛好卡在邊界值的題目一定要親手代入驗算。
✅
switch 貫穿口訣
「沒 break 不停,一路溜到底」——貫穿只看有沒有 break,不會重新比對 case 標籤的數字。
✅
分辨有意/無意貫穿
case 之間緊鄰無程式碼=刻意分組共用;case 中間夾程式碼卻無 break=多半是忘記寫。
✅
enum 編號規則
沒指定值=前一個成員+1;有指定值=直接採用該數字,之後繼續從該數字+1遞增。
✅
= 與 == 不要混淆
if(a=5) 是賦值(恆為真,因5非0);if(a==5) 才是比較,統測最愛考手誤陷阱。
✅
邏輯除錯先問語意
先確認 flag 變數原本代表什麼意思,再檢查後續 !flag 等用法是否呼應這個語意,而不是先懷疑運算子。