111 身心障礙特考三等 資訊處理 程式語言 考古題詳解
第 一 題25 分
請回答下列有關物件導向程式語言的問題:
(一) 物件導向程式語言的特性有哪些?並分別說明之。(10 分)
(二) 以你學過的物件導向程式語言,撰寫你在(一)所描述之各別特性所對應的程式片段。(15 分)
登入後即可作答並保存紀錄。
核心觀念
本題考查物件導向程式設計(Object-Oriented Programming, OOP)的基本特性,以及如何用程式碼呈現這些特性。常見的核心特性為封裝、繼承、多型與抽象。有些教材把抽象視為封裝與介面設計的一部分,或將訊息傳遞另列為特性;作答時應清楚說明所採用的分類,並使各段程式碼與定義相符。
- 封裝(Encapsulation):把資料與操作資料的方法放在同一個類別中,並控制外部存取方式,以維護物件狀態的一致性。
- 繼承(Inheritance):子類別承接父類別的欄位與方法,並可擴充或改寫行為,以重用既有程式碼。
- 多型(Polymorphism):不同類別的物件可透過相同的介面或方法呼叫,依實際物件類型執行各自的行為。
- 抽象(Abstraction):只呈現使用者需要的操作與概念,隱藏不必要的實作細節;常以抽象類別或介面定義共同規格。
解題方法
採 Java 示範,分別以類別存取控制、extends、方法覆寫及 abstract 方法對應上述四項特性。多型的程式片段同時呈現繼承與動態繫結;實際作答時可註明此處著重說明多型,避免將兩項概念混為一談。
程式片段與特性說明
一、封裝
class BankAccount {
private double balance; // 外部不能直接存取
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
public double getBalance {
return balance;
}
}
balance 宣告為 private,外部須透過公開方法存款或查詢餘額。deposit 可檢查金額,避免任意修改資料,這就是以方法控制物件狀態的封裝。
二、繼承
class Animal {
public void eat {
System.out.println("進食");
}
}
class Dog extends Animal {
public void bark {
System.out.println("吠叫");
}
}
Dog 以 extends 繼承 Animal,因此可使用 eat,也可加入自己的 bark。繼承呈現「Dog 是一種 Animal」的類別關係,適合描述具共通性又需擴充的類別。
三、多型
第 二 題25 分
請說明函式之間的呼叫方式,其實際參數(actual parameter)與形式參數(formal parameter)的傳送有哪幾種?並撰寫對應的程式片段加以說明。(25 分)
登入後即可作答並保存紀錄。
核心觀念
本題考查函式呼叫時,呼叫端的實際參數(actual parameter)如何與被呼叫函式的形式參數(formal parameter)建立關係。
- 實際參數:呼叫函式時寫在括號內的引數,例如
swap(a, b)中的a、b。 - 形式參數:函式定義中接收引數的變數,例如
void swap(int x, int y)中的x、y。 - 兩者的傳送方式會影響函式內修改參數時,呼叫端的變數是否跟著改變。
常見參數傳送方式包括:傳值呼叫、傳址呼叫、傳參考呼叫、傳值結果呼叫;程式語言也可能採用傳名呼叫。不同語言支援的方式不盡相同。
解題方法
作答時先說明各種方式的核心差異,再用相同的交換兩數範例比較:函式內修改形式參數後,呼叫端的 a、b 是否改變。如此可清楚呈現參數與變數之間是複製數值、傳遞位置,或建立別名關係。
以下以類 C 語法示範;「傳參考」與「傳值結果」的片段採概念性語法表示,因各語言的語法不同。
一、傳值呼叫(call by value)
將實際參數的值複製給形式參數。函式內修改形式參數,只會改變區域副本,不會改變呼叫端變數。
void setValue(int x) {
x = 99;
}
int main(void) {
int a = 10;
setValue(a);
// a 仍為 10
}
呼叫時,x 得到 a 的值 10;x = 99 不會回寫至 a。這是 C 語言一般參數傳遞的方式。
二、傳址呼叫(call by reference/address)
將實際參數所在的記憶體位置傳給函式;形式參數透過該位置存取呼叫端變數,因此修改會反映到原變數。C 可用指標明確呈現此效果:
void setValue(int *p) {
*p = 99;
}
int main(void) {
int a = 10;
setValue(&a);
// a 為 99
}
呼叫端傳入 a 的位址 &a,函式透過 *p 改寫該位址所存的值。嚴格區分時,C 傳入的指標本身仍是以傳值方式傳遞;但透過指標可達成修改原變數的效果。
第 三 題25 分
請解釋並舉例說明何謂多載函式(overloaded function)與樣版函式(template function)?(25 分)
登入後即可作答並保存紀錄。
核心觀念
本題考查 C++ 的函式多載(function overloading)與函式樣版(function template),重點在於兩者如何讓同一個函式名稱處理不同型別的資料,以及其實作方式有何不同。
- 多載函式:在同一作用範圍內,宣告多個同名函式,並以參數個數、參數型別或參數順序區分。呼叫時,編譯器依據實際引數選擇最合適的函式。
- 樣版函式:以型別參數描述一個通用的函式樣板;呼叫時,編譯器依據引數型別推導樣版參數,再產生適用的函式版本。
解題方法
回答時分別交代兩種機制的定義、辨識依據與程式例子,再比較其差異。特別注意:不能只靠回傳型別不同來形成多載;樣版函式則以型別參數重用同一套函式邏輯。
一、多載函式
以下以不同型別的參數多載 printValue:
#include <iostream>
using namespace std;
void printValue(int x) {
cout << "整數:" << x << '\n';
}
void printValue(double x) {
cout << "浮點數:" << x << '\n';
}
int main {
printValue(10); // 呼叫 printValue(int)
printValue(3.14); // 呼叫 printValue(double)
}
兩個函式名稱相同,但參數型別不同。printValue(10) 的引數是 int,因此選擇 printValue(int);printValue(3.14) 的引數是 double,因此選擇 printValue(double)。
多載也可以依參數個數區分,例如:
int add(int a, int b) {
return a + b;
}
int add(int a, int b, int c) {
return a + b + c;
}
呼叫 add(2, 3) 會選擇兩個參數的版本;呼叫 add(2, 3, 4) 則會選擇三個參數的版本。
二、樣版函式
若函式對不同型別的處理邏輯相同,可以使用函式樣版:
第 四 題25 分
程式語言中變數要給予資料型態,其作用為何?同時請說明何謂靜態連結(static binding)和動態連結(dynamic binding)的作用時機點及其優缺點。(25 分)
登入後即可作答並保存紀錄。
核心觀念
本題考查變數的資料型態,以及型態或其他程式性質何時確定,也就是**靜態連結(static binding)與動態連結(dynamic binding)**的差異。此處的「連結」是指把程式中的名稱或運算式,與其型態、儲存位置或實際操作方式等資訊建立關係。
變數指定資料型態的作用
資料型態說明變數可表示的資料種類及其操作方式。為變數指定型態,主要有以下作用:
- 界定可儲存的值與範圍:例如整數、浮點數、字元或布林值;特定型態也會限制可表示的範圍與精度。
- 決定可執行的運算:型態會影響運算子的意義,例如整數加法、浮點數加法或字串串接。
- 配置儲存空間與表示方式:編譯器或執行環境依型態決定資料的記憶體表示、大小與對齊方式。
- 協助檢查程式錯誤:型態檢查可以發現不相容的指定或運算,並在編譯期或執行期報錯。
- 提升程式可讀性與維護性:明確的型態能表達程式設計者對資料用途的預期,讓程式較容易理解與修改。
靜態連結與動態連結
靜態連結(static binding)
靜態連結是在編譯期確定某項程式性質與其對應關係。常見例子包括變數型態、函式呼叫所對應的函式,以及某些名稱的作用範圍。確定後,執行期間通常不必再依當下情況重新判定。
優點:
- 編譯器可提早發現型態不相容等錯誤。
- 執行時少了查詢或判定步驟,效率通常較高。
- 程式行為較容易預測,也較利於編譯器最佳化。
缺點: