110 身心障礙特考三等 資訊處理 程式語言 考古題詳解
第 一 題20 分
在程式語言中有所謂的早期繫結(early binding)和晚期繫結(late binding),請詳述這兩個繫結的差異性和使用時機點,並以 C++ 程式語言說明如何達成晚期繫結的功能。
登入後即可作答並保存紀錄。
核心觀念
「繫結」(binding)是指程式中的名稱、運算或呼叫,與其所代表的實際實體或程式碼建立關聯。早期繫結與晚期繫結的差異,在於這項關聯於何時決定:
- 早期繫結(early binding):在編譯期或連結期決定呼叫目標。呼叫哪個函式,通常可由函式名稱、參數型別及呼叫位置確定。
- 晚期繫結(late binding):在執行期才依實際物件的型別或狀態決定呼叫目標。同一個呼叫可因執行時的物件不同而執行不同程式碼。
解題方法
作答時可從「繫結時間、判斷依據、適用時機」三方面比較,再以 C++ 的虛擬函式示範執行期派送。
C++ 的一般非虛擬成員函式採靜態繫結。透過基底類別指標或參考呼叫非虛擬函式時,呼叫目標依指標或參考的宣告型別決定。若將基底類別函式宣告為 virtual,且衍生類別覆寫該函式,則透過基底類別指標或參考呼叫時,會依物件的實際型別在執行期派送,達成晚期繫結。
#include <iostream>
using namespace std;
class Base {
public:
virtual void show const {
cout << "Base\n";
}
virtual ~Base = default;
};
class Derived : public Base {
public:
void show const override {
cout << "Derived\n";
}
};
int main {
Derived object;
Base* ptr = &object;
ptr->show; // 輸出 Derived
}
第 二 題20 分
函式之間的呼叫,其參數的傳送可分為哪幾種?請詳述之,並以任何一種程式語言撰寫兩個整數對調的情形,並加以說明最後處理的結果。需註明使用的程式語言。
登入後即可作答並保存紀錄。
核心觀念
函式呼叫時,呼叫端會把實際參數(argument)傳給被呼叫函式的形式參數(parameter)。常見的參數傳送方式如下:
- 傳值呼叫(call by value):將實際參數的值複製給形式參數。函式內修改形式參數,只改變副本,不影響呼叫端的變數。
- 傳址呼叫(call by reference):形式參數直接參照呼叫端變數;在函式內修改參數,會改變原變數。
- 傳結果呼叫(call by result):形式參數只用於輸出。函式執行時不取用呼叫端變數的初值,返回時再將形式參數的值寫回實際參數。
- 傳值-結果呼叫(call by value-result,又稱 copy-in/copy-out):呼叫時先將實際參數的值複製到形式參數,返回時再將形式參數的值複製回實際參數。
- 傳名呼叫(call by name):形式參數的運算式在函式使用時才求值,效果近似將實際參數運算式代入函式本文;在某些語言或情境下,每次使用都會重新求值。
參數傳送方式會影響函式內的賦值是否改變呼叫端資料。以下用傳參考的方式交換兩個整數。
解題方法
使用 C++ 的參考參數(reference parameter),讓函式參數直接參照呼叫端的兩個整數。交換時以暫存變數保存其中一個值,避免覆寫後遺失。
第 三 題30 分
程式語言中有一重要的主題是指標(pointer)。何謂指標?其功用為何?
給定 ,並詳述下列各項:
(1)
(2)
(3)
(4)
(5)
登入後即可作答並保存紀錄。
核心觀念
指標(pointer)是用來存放記憶體位址的變數。若指標所存的位址對應到某個物件,就能透過指標間接讀取或修改該物件。
&a:取出變數a的位址。*ptr:依指標ptr儲存的位址,存取該處的值。- 指標型別決定如何解讀該位址,以及對指標做指標運算時的步長。例如
int *指標遞增時,會前進一個int的大小。
本題給定 int a = 100;,並考查指標、函式宣告、陣列及函式指標的型別判讀。解讀宣告時,先找識別字,再由識別字向外讀取;括號會改變 * 與陣列、函式宣告的結合順序。
解題方法與各項說明
(1) int *ptr = &a
由識別字 ptr 向外看,*ptr 表示 ptr 是指標;int 表示它指向 int 型別的物件。因此 ptr 的型別是「指向 int 的指標」。
&a 是變數 a 的位址,型別為 int *,正好可指定給 ptr。執行後,ptr 指向 a,而 *ptr 的值為 100。透過 *ptr 修改值,也會改變 a。
(2) int *fn(int a)
先看 fn(int a):fn 後接參數列,表示 fn 是函式,接受一個 int 參數。前面的 int * 表示函式回傳「指向 int 的指標」。
因此,fn 是「接受一個 int、回傳 int * 的函式」。這項宣告本身不是函式指標,也沒有提供函式本體或呼叫結果。
(3) int (*fn)(int a)
括號使 *fn 優先與識別字結合,故 fn 是指標;其後的 (int a) 表示它指向一個接受 int 參數的函式;最前方的 int 表示該函式回傳 int。
因此,fn 是「指向接受一個 int、回傳 int 之函式的指標」。它可指向符合此型別的函式;呼叫時可寫成 fn(參數值)。
(4) int *arr[3]
arr[3] 表示 arr 是含有 3 個元素的陣列;每個元素的型別由前面的 int * 決定,都是「指向 int 的指標」。
第 四 題30 分
程式語言中有一重要的主題是指標和參考(reference),它們常用來撰寫鏈結串列或樹狀結構的問題。我們將它用來處理鏈結串列,假設有一單向鏈結串列(singly linked list)之節點中有三個項目,分別是:
- (整數型態)
- (浮點數型態)
- (指標或參考型態)
如下圖所示:
🖼️【此處有附圖,請對照原卷】
今有一節點名為 ,試分別撰寫將此 節點加入於已含有多個節點的單向鏈結串列之尾端,以及刪除鏈結串列尾端節點的片段程式。可以任何程式語言撰寫之,但請註明使用的程式語言。
登入後即可作答並保存紀錄。
核心觀念
本題考查單向鏈結串列的指標操作:
next指向同一串列中的下一個節點;尾端節點的next為空指標。- 尾端插入時,找到原尾端,讓它的
next指向新節點ptr。 - 刪除尾端時,必須找到尾端及其前一個節點,將前一個節點的
next設為空指標,再釋放尾端節點的記憶體。單向鏈結串列無法由尾端直接找到前一個節點,因此需要從串列開頭走訪。
解題方法
以下使用 C++。假設節點定義如下,且加入的 ptr 尚未連入串列:
struct Node {
int id;
float score;
Node* next;
};
將 ptr 加入串列尾端
void append(Node*& head, Node* ptr) {
if (ptr == nullptr) return;
ptr->next = nullptr; // 新節點成為尾端
if (head == nullptr) {
head = ptr;
return;
}
Node* current = head;
while (current->next != nullptr) {
current = current->next;
}
current->next = ptr;
}
current 逐節點往後移動,直到原尾端,也就是 current->next == nullptr。再將原尾端的 next 指向 ptr,完成接尾。