107 高普考普通考試 資訊處理 程式設計概要 考古題詳解
第 一 題30 分
請回答以下對 C/C++ 程式語言的敘述正確與否。如果敘述是錯誤的,需說明正確敘述為何。每小題 3 分,共 30 分。
(1) 程式執行的結果與預期的不同,這種錯誤稱為執行期錯誤(Runtime Error)。
(2) C/C++ 屬自由格式(Free-Form)、隱含型別宣告(Implicit Type Declaration)程式語言。
(3) switch 選擇結構中,default 敘述為選擇性,故可省略。
(4) 陣列(Array)無法存放一連串資料型別不同的相關資料。
(5) 當 && 運算子中的只要有一個運算元為真時,則該運算式的結果為真。
(6) 可使用結構(Structure)陣列變數的名稱指向該陣列中的任一個資料。
(7) 程式在編譯階段即配置完成其所需記憶體的方式稱為動態記憶體配置(Dynamic Memory Allocation)。
(8) 當不同的物件收到相同的訊息時,會以各自的方法作處理的特點稱為多載(Overloading)。
(9) 子類別將繼承自父類別的方法重新定義,而且不會影響到父類別的方法,這個特點稱為多載(Overloading)。
(10) 子類別可多重繼承自父類別內所有的資料成員與成員函數。
登入後即可作答並保存紀錄。
核心觀念
本題評量 C/C++ 程式語言的基礎語法、編譯與執行機制、記憶體管理,以及物件導向程式設計(OOP)的核心概念,涵蓋四大範疇:
- 程式除錯與錯誤類型:語法錯誤(Syntax Error)、執行期錯誤(Runtime Error)與邏輯錯誤(Logic Error)之本質差異。
- 型別系統與基本控制結構:自由格式(Free-Form)、顯式型別宣告(Explicit Type Declaration)、條件分支
switch-case之語法規範與陣列(Array)之同質性特點。 - 運算子與記憶體配置:邏輯運算子短路評估與真值表規則、陣列名稱作為常數指標(Constant Pointer)之限制、靜態配置(Compile-time/Static Allocation)與動態配置(Runtime/Dynamic Allocation)之時機。
- 物件導向特性(OOP):封裝存取控制、多型(Polymorphism)、多載(Overloading)、覆寫(Overriding)之嚴格學理定義,以及多重繼承(Multiple Inheritance)之概念。
解題方法
本題為國家考試常見之「是非兼改錯題」。解答時採取以下切入原則:
- 精確辨析正誤:第一時間對敘述的正確性做出明確判定(「正確」或「錯誤」)。
- 鎖定關鍵錯誤點並修正:若敘述錯誤,指出其混淆或誤用的專有名詞,並以標準的學理定義重構完整的正確敘述。公職考試閱卷通常採正誤判斷與改錯說明分別給分,因此修正說明須語意完整、論理清晰,不可僅換改單字。
選項分析
(1) 程式執行的結果與預期的不同,這種錯誤稱為執行期錯誤(Runtime Error)。
- 判斷:錯誤
- 分析與正確敘述:
- 分析:程式可正常編譯並完整執行完畢,但計算結果或輸出行為與預期不符,此類錯誤稱為「邏輯錯誤(Logic Error)」或「語意錯誤(Semantic Error)」。而「執行期錯誤(Runtime Error)」是指程式在執行過程中觸發未預期的異常狀況(如除以零、記憶體非法存取 Segmentation Fault、堆疊溢位 Stack Overflow 等),導致程式非正常中斷崩潰(Crash)。
- 正確敘述:程式執行的結果與預期的不同,這種錯誤稱為邏輯錯誤(Logic Error);執行期錯誤(Runtime Error)是指程式執行期間因異常事件導致程式崩潰或非正常中斷的錯誤。
(2) C/C++ 屬自由格式(Free-Form)、隱含型別宣告(Implicit Type Declaration)程式語言。
- 判斷:錯誤
- 分析與正確敘述:
- 分析:C/C++ 確實屬於「自由格式(Free-Form)」語言(程式碼排版中的空格、縮排與換行不影響編譯語法,以分號
;作為敘述結尾);但 C/C++ 屬於「靜態型別(Statically-Typed)」且必須為「顯式型別宣告(Explicit Type Declaration)」語言。所有變數在宣告與使用前,皆必須明確指定其資料型別(如int、double、char等),編譯器在編譯期即完成型別檢查。 - 正確敘述:C/C++ 屬自由格式(Free-Form)、顯式型別宣告(Explicit Type Declaration)程式語言。
(3) switch 選擇結構中,default 敘述為選擇性,故可省略。
- 判斷:正確
- 分析:
- 在 C/C++ 語言標準規範中,
switch語法區塊內的default:標籤屬於可選項目(Optional)。若所有的case常數值皆未匹配,且程式碼中未定義default:,則程式會直接跳過整個switch結構,繼續執行後續程式碼,不會引發編譯或執行錯誤。
(4) 陣列(Array)無法存放一連串資料型別不同的相關資料。
- 判斷:正確
- 分析:
- 陣列在資料結構與 C/C++ 語法定義上屬於「同質性(Homogeneous)」資料結構,配置於一段連續的記憶體位址中,每個元素必須具有相同的資料型別與固定大小。若要將一連串資料型別不同的相關資料組合在一起,必須使用「結構(
struct)」、「聯合(union)」或「類別(class)」等異質性(Heterogeneous)自訂型別。
(5) 當 && 運算子中的只要有一個運算元為真時,則該運算式的結果為真。
- 判斷:錯誤
- 分析與正確敘述:
- 分析:
&&為邏輯 AND(邏輯且)運算子,根據布林邏輯真值表,必須在「所有(兩個)運算元皆為真(true)」時,整體運算式之結果才為真;只要其中有一個運算元為假(false),結果即為假。題目所述「只要有一個運算元為真時結果即為真」是邏輯 OR(邏輯或,||運算子)的特性。 - 正確敘述:當
&&運算子中的所有運算元皆為真時,該運算式的結果才為真(或:當||運算子中的只要有一個運算元為真時,則該運算式的結果為真)。
(6) 可使用結構(Structure)陣列變數的名稱指向該陣列中的任一個資料。
- 判斷:錯誤
- 分析與正確敘述:
- 分析:在 C/C++ 中,陣列變數名稱在數值上等於陣列首個元素的記憶體位址(即
&array[0]),其本質為一個「常數指標(Constant Pointer)」,不可被重新賦值(Non-modifiable lvalue)。因此陣列名稱固定指向陣列的第一個元素,無法任意修改其指向來指到陣列中的任一資料。若要存取或指向其他元素,必須透過下標運算子(如array[i])、指標算術偏移(如*(array + i)),或是額外宣告可變的指標變數(Pointer Variable)來承接位址。 - 正確敘述:結構陣列變數的名稱為常數指標,固定指向該陣列的第一個元素(索引 0),無法任意變更指向;若要指向或存取其他元素,須使用索引下標
[i]、指標運算或額外宣告指標變數。
(7) 程式在編譯階段即配置完成其所需記憶體的方式稱為動態記憶體配置(Dynamic Memory Allocation)。
- 判斷:錯誤
- 分析與正確敘述:
第 二 題10 分
請問以下程式輸出的結果為何?(10 分)
#include <iostream> #include <cstdlib> using namespace std;
int main(void) { int i = 0, sum = 0;
while (i < 21) {
if (i % 3 != 0) {
i++;
continue;
}
sum += i++;
}
cout << "i=" << i << ", SUM=" << sum << endl;
return 0;
}
登入後即可作答並保存紀錄。
核心觀念
本題考查 C++ 基本流程控制與運算子行為,核心要點包含:
while迴圈控制結構:進入與終止迴圈的布林條件判斷。- 條件分支與跳躍陳述式(
continue):continue會立即中斷本次迴圈的後續程式碼,直接回到迴圈開頭進行下一次的條件判斷(在while迴圈中,不會跳過條件檢查)。 - 模數運算子(
%,取餘數):以i % 3 != 0篩選非 3 的倍數。 - 複合指定運算子(
+=)與後置遞增運算子(i++):後置遞增(Post-increment)的特性為「先取原本的值參與運算,運算結束或敘述句完畢後再遞增 1」。
解題方法
1. 迴圈流程與變數遞增規律
初始狀態:,。
迴圈每次執行時,條件檢查為 :
- 分支一:若 不是 3 的倍數(
i % 3 != 0) 執行i++;,接著執行continue;跳過後續敘述。此分支使 增加 1,並進入下一輪。 - 分支二:若 是 3 的倍數(
i % 3 == 0) 條件不成立,跳過if區塊,執行sum += i++;。 此敘述可拆解為兩步:
sum = sum + i;(將目前 的值累加至sum)i = i + 1;( 完成後置遞增)
關鍵結論:無論進入分支一還是分支二, 在每一次迴圈迭代中都會確實加 1。因此, 會依序歷經整數數列:
2. 累加數值推導(sum)
只有當 為 3 的倍數(即 )時,才會被累加進 sum。在 的範圍內,符合條件的 值為:
數值累加計算過程如下:
第 三 題10 分
請問以下程式輸出的結果為何?(10 分)
#include <iostream> #include <cstdlib> using namespace std;
void fun1(int, int); void fun2(int *, int *); void fun3(int *, int, int);
int main(void) { int a[] = {1, 2, 3, 4, 5}, i;
fun1(a[1], a[3]);
fun2(a, a + 2);
fun3(a, 5, 0);
cout << "執行所有函數後,陣列的內容為:" << endl;
for (i = 0; i < 5; i++)
cout << "a[" << i << "]=" << a[i] << endl;
return 0;
}
void fun1(int x, int y) { int tmp;
tmp = y;
y = x;
x = tmp;
}
void fun2(int *x, int *y) { int tmp;
tmp = *y;
*y = *x;
*x = tmp;
}
void fun3(int *ptr, int n, int num) { *(ptr + n - 1) = num; }
登入後即可作答並保存紀錄。
核心觀念
本題評量 C++ 語言中參數傳遞機制(Parameter Passing)與指標運算(Pointer Arithmetic)的核心觀念:
- 傳值呼叫(Call by Value):呼叫函式時僅複製引數的值給函式的區域參數。函式內部對參數的任何修改均不會影響呼叫端的原始變數。
- 傳指標/傳址呼叫(Call by Pointer / Address):呼叫函式時傳遞變數的記憶體位址,函式內部透過反參考運算子(Dereference Operator,
*)可直接存取與修改呼叫端記憶體內的資料,產生副作用(Side Effect)。 - 陣列與指標算術(Pointer Arithmetic):在 C/C++ 中,陣列名稱可隱式轉換為指向其首元素的指標(即
a等價於&a[0])。指標加上整數位移量 (即ptr + k)代表向後移動 個元素位址,且語法上*(ptr + k)完全等價於ptr[k]。
解題方法(程式逐步追蹤)
1. 初始狀態
程式於 main 中宣告並初始化一維陣列:
int a[] = {1, 2, 3, 4, 5}, i;
陣列大小為 ,初始內容為:
2. 步驟一:追蹤 fun1(a[1], a[3]);
- 呼叫機制:函式原型為
void fun1(int, int);,採傳值呼叫。 - 傳遞數值:複製 的值()給區域變數 ,複製 的值()給區域變數 。
- 函式執行:
tmp = y; // tmp = 4
y = x; // y = 2
x = tmp; // x = 4
- 執行結果:對調的僅為
fun1內部的區域變數 與 ,函式結束後該堆疊框架(Stack Frame)釋放,主程式陣列 的內容完全不受影響。 - 陣列當前狀態:
{1, 2, 3, 4, 5}。
3. 步驟二:追蹤 fun2(a, a + 2);
- 呼叫機制:函式原型為
void fun2(int *, int *);,採傳指標呼叫。 - 傳遞位址:
- 引數
a為首元素位址&a[0],賦予指標變數 。 - 引數
a + 2經指標算術為第三個元素位址&a[2],賦予指標變數 。 - 函式執行:
第 四 題10 分
以下是一個完整的 Python 程式,請問執行後的結果為何?(10 分)
for i in range(1, 7): # 產生一個 1, 2, 3, 4, 5, 6 的整數序列 for j in range(i, 1, -1): # -1 表示階值(step value) print(" ", end="")
for j in range(1, 7 - i + 1):
print(j, end="")
print()
登入後即可作答並保存紀錄。
核心觀念
本題主要測驗 Python 程式語言的基礎語法與控制結構,重點涵蓋以下三個核心:
range函式的區間特性與步進值(Step):
range(start, stop[, step])產生的序列為「左閉右開」半開區間 ,即包含 但不包含 。- 當 (正步進)時,序列條件為 。
- 當 (負步進)時,序列條件為 。
print函式的引數控制:
- 預設情況下,
print輸出後會自帶換行符號(\n)。 - 設定
end=""會取消自動換行,使後續輸出緊接著在同一列呈現。 - 獨立的
print則用於輸出一道換行指令。
- 巢狀迴圈(Nested Loops)與圖形輸出邏輯:
- 外層迴圈控制「列數(Row)」。
- 第一個內層迴圈控制「每列開頭的空白格數(Indentation / Padding)」。
- 第二個內層迴圈控制「每列輸出的數字內容(Content)」。
解題方法
本題為經典的雙層巢狀迴圈圖形輸出追蹤題,解題切入點在於推導出「外層變數 」與「兩個內層迴圈次數」之間的數學函數關係。
1. 迴圈結構推導
- 外層迴圈:
for i in range(1, 7): - 的取值序列為 ,總共迭代 6 列。
- 第一內層迴圈(印空白):
for j in range(i, 1, -1): - 步進值為 ,終止條件為 。
- 走訪元素為 ,共執行 次。
- 效果:在第 列開頭印出 個空格。
- 第二內層迴圈(印數字):
for j in range(1, 7 - i + 1): - 相當於
range(1, 8 - i),步進值預設為 ,終止條件為 。 - 走訪元素為 ,共輸出 個連續數字。
- 換行:
print於每列末端換行。
2. 逐列追蹤表(Trace Table)
| 列數 () | 空白迴圈 range(i, 1, -1) | 空白個數 () | 數字迴圈 range(1, 8 - i) | 印出數字 | 該列完整輸出結果 |
第 五 題20 分
撰寫一個完整的 C/C++、Java 或 Python 程式,讓使用者輸入姓名(name)、小考成績(quiz)、期中考成績(midterm)與期末考成績(final)後,將這三個成績傳入呼叫函數 calScore(),該函數需傳回所計算後的學期成績;程式再將學期成績傳入呼叫函數 calGrade(),該函數需傳回成績等第結果;最後程式需從螢幕顯示出使用者所輸入的姓名、學期成績與成績等第結果。
程式顯示結果後,需再詢問使用者是否繼續輸入。當使用者輸入 ’Y’ 或 ’y’ 時則繼續輸入,否則結束離開程式。(20 分)
學期成績計算公式為:
成績等第標準如下:
學期成績 :A
學期成績 :B
學期成績 :C
學期成績 :D
學期成績 :F
登入後即可作答並保存紀錄。
核心觀念
本題為典型的模組化程式設計與互動式流程控制考題,重點考核以下核心能力:
- 模組化函數設計(Modular Programming):包含函數的原型宣告、參數傳遞(Pass by Value)與傳回值(Return Value)機制。
- 多向條件分支(Multi-way Selection):使用階梯式
if-else if-else結構對數值區間進行分類。 - 重複控制結構(Repetition Structure):利用條件迴圈(如
do-while或while)實作使用者互動式(Interactive)重複執行機制。 - 標準輸入與輸出(Standard I/O):正確處理字串、浮點數及字元的輸入,特別是處理鍵盤輸入緩衝區中的殘留換行字元。
解題方法
本題要求撰寫完整程式,採用由上而下(Top-Down)的結構化設計:
- 函數一:學期成績計算函數
calScore
- 參數:接收三個浮點數,分別為小考成績(
quiz)、期中考成績(midterm)與期末考成績(final)。 - 計算公式:
- 傳回值:計算後的加權學期成績(浮點數型態)。
- 函數二:等第判定函數
calGrade
- 參數:接收計算後的學期成績(浮點數型態)。
- 邏輯設計:題目給定的標準雖寫為整數區間(如 ),但學期成績乘上權重後多為實數(含小數)。為避免浮點數如 掉出判斷區間,應採用由高至低的連續遞減門檻判定:
- 若 ,傳回
'A' - 否則若 (即涵蓋 ),傳回
'B' - 否則若 (即涵蓋 ),傳回
'C' - 否則若 (即涵蓋 ),傳回
'D' - 其餘情況(即 ),傳回
'F' - 傳回值:成績等第(字元型態)。
- 主程式控制流程(
main)
- 使用
do-while迴圈(至少執行一次)。 - 迴圈內部依序執行:
- 提示並讀取使用者輸入之姓名、三項成績。
- 呼叫
calScore計算學期成績。 - 呼叫
calGrade取得等第。 - 輸出姓名、學期成績與等第。
- 詢問是否繼續,讀取字元後判斷是否為
'Y'或'y',決定是否再次進入迴圈。
選項分析
本題為國家考試之程式撰寫實作題(非選擇題),無選項分析。評分焦點在於:
- 函數名稱、傳入參數與回傳值型態是否完全依題目指定定義。
- 計算公式與等第分類邏輯的正確性。
- 迴圈控制與使用者輸入判斷是否完整且無死迴圈。
解題技巧
- 函數名稱必須完全符合題意:題目已指定函數名為
calScore與calGrade,大小寫必須完全一致,切勿自作聰明更名(如改為calculateScore),否則必定扣分。 - 成績型態請務必使用浮點數(
double或float):權重比例包含 與 ,計算過程會產生小數,若使用整數(int)儲存或運算將導致截尾誤差。 - C 語言輸入緩衝區(Input Buffer)陷阱:在讀取浮點數後接著使用
scanf("%c", &choice)讀取字元時,前一次輸入所鍵入的「換行鍵(\n)」會殘留在緩衝區內,造成字元讀取直接跳過。解法為在格式字串加上前導空格:scanf(" %c", &choice);,使scanf自動忽略所有空白與換行字元。
【答案】
以下提供兩種符合國考評分規範的完整程式實作:
答案方案一:C 語言實作(公職考試最通用標準解)
第 六 題20 分
撰寫一個完整的 C/C++、Java 或 Python 程式,以物件導向方式設計一個名為 transcript 的類別,此類別包括以下屬性與方法:(20 分)
(1) name 代表姓名的私有(private)字串資料項目。
(2) quiz 代表小考成績的私有數值資料項目。
(3) midterm 代表期中考成績的私有數值資料項目。
(4) final 代表期末考成績的私有數值資料項目。
(5) 建構函數可將新建立物件之姓名作初始化。
(6) 設計 calScore() 公有方法計算學期成績(score)的私有數值資料項目。
(7) 設計 calGrade() 公有方法計算成績等第(grade)的私有字元資料項目。
(8) 設計 printReport() 方法從螢幕顯示出學生姓名、學期成績與成績等第結果。
(9) 學期成績計算公式與成績等第標準同第五題。
程式需設計迴圈讓使用者輸入資料以驗證程式的正確性,直到使用者輸入 ’n’ 或 ’N’ 時結束程式。
登入後即可作答並保存紀錄。
核心觀念
本題主要測驗物件導向程式設計(Object-Oriented Programming, OOP)的基本架構與語法實作能力,核心觀念包含:
- 封裝(Encapsulation)與存取權限控制:
- 類別內部的資料項目(屬性)宣告為私有(
private),防止外部程式直接存取竄改,確保資料安全性。 - 透過公有(
public)方法提供對外的操作介面,實現資訊隱藏(Information Hiding)。
- 建構函數(Constructor):
- 物件實體化時自動執行的特殊方法,用以初始化物件之成員變數(本題指定初始化
name)。
- 加權計算與多條件分支邏輯:
- 題目規格 (9) 承襲該年度第五題之規定:
- 學期成績計算公式:
- 成績等第標準:
- 迴圈控制結構與終止條件比對:
- 使用
do-while結構反覆接收使用者輸入與執行驗證,並藉由布林條件式比對字元,直到輸入'n'或'N'時跳出迴圈。
解題方法
- 實作語言選定:
本題以 C++ 撰寫。C++ 具備嚴謹的物件導向機制,且屬性名稱
final在 C++ 中屬於上下文識別字(Contextual Keyword),可直接合法作為成員變數名稱,能 精確吻合題目規格要求。 - 類別結構設計(
transcript類別):
- 私有資料項目(
private): name:字串型態(std::string)。quiz、midterm、final、score:數值型態,因加權計算涉及小數點,採用雙精度浮點數(double)。grade:字元型態(char)。- 公有介面方法(
public): transcript(string n):建構函數,將參數傳入之姓名指派給name,並將成績成員賦予初值。setScores(double q, double m, double f):公有輔助方法,供主程式輸入三項考卷分數後寫入私有屬性。calScore:套用加權公式計算學期成績,更新內部私有屬性score並回傳。calGrade:以階梯式if - else if - else結構評定等第,更新內部私有屬性grade並回傳。printReport:於螢幕輸出姓名、學期成績與成績等第。
- 主程式控制流程設計(
main函式):
- 採用
do-while迴圈架構,確保程式至少執行一次。 - 每次迴圈依序提示並讀取姓名與三項成績,建立
transcript物件、設定成績,並循序呼叫calScore、calGrade與printReport。 - 提示使用者輸入是否繼續,讀入字元
choice。迴圈延續條件定為:(choice != 'n' && choice != 'N')。
選項分析
本題為程式實作申論題(非選擇題),無選項可資比對。以下針對題目給定之 (1) 至 (9) 項規格要求及迴圈條件進行逐項檢視與規格落實分析:
- (1)~(4) 私有資料項目:
name、quiz、midterm、final均明確宣告於private區塊,落實物件導向封裝原則。- (5) 建構函數初始化姓名:
- 定義建構函數
transcript(string n),在物件生成時以引數指派姓名,符合初始化規範。 - (6)
calScore方法: - 宣告為
public double calScore,內部執行加權公式運算並存入私有成員score。 - (7)
calGrade方法: - 宣告為
public char calGrade,內部依據score數值計算評級並存入私有成員grade。 - (8)
printReport方法: - 宣告為
public void printReport,負責標準輸出(std::cout)顯示報表資訊。 - (9) 引用第五題之公式與標準:
- 權重嚴格設定為小考 、期中考 、期末考 ;等第精確落於 A、B、C、D、F 五個級距。
- 迴圈終止條件:
- 題目要求「直到使用者輸入
'n'或'N'時結束」,對應的繼續執行條件為「輸入字元既非'n'且非'N'」,邏輯運算式為choice != 'n' && choice != 'N'。
解題技巧
- 語言選擇之保留字陷阱:
- 題目指定期末考成績屬性名稱為
final。