普考申論題
114年
[資訊處理] 程式設計概要
第 七 題
📖 題組:
依據以下 C 程式碼,回答下列問題:
1 #include
2 #include
3 #include
4 #define MAXWL 21
5 #define MAXWS 100
6 int c1(const char* s1, const char* s2) {
7 while (*s1 && *s1 == *s2) {
8 s1++;
9 s2++;
10 }
11 return *s1 - *s2;
12 }
13 int c2(const char* s) {
14 int len = 0;
15 while (s[len]) len++;
16 return len;
17 }
18 int main() {
19 char** words = malloc(MAXWS * sizeof(char*));
20 int count = 0;
21 char buffer[MAXWL];
22 while (1) {
23 if (fgets(buffer, MAXWL, stdin) == NULL) break;
24 buffer[strcspn(buffer, "\n")] = '\0';
25 if (buffer[0] == '\0') break;
26 words[count] = malloc(c2(buffer) + 1);
27 strcpy(words[count], buffer);
28 count++;
29 }
30 for (int i = 0; i < count; i++) {
31 printf("Word: %s, Length: %d\n", words[i], c2(words[i]));
32 }
33 for (int i = 0; i < count - 1; i++) {
34 for (int j = 0; j < count - i - 1; j++) {
35 if (c1(words[j], words[j + 1]) > 0) {
36 char* temp = words[j];
37 words[j] = words[j + 1];
38 words[j + 1] = temp;
39 }
40 }
41 }
42 printf("Sorted words:\n");
43 for (int i = 0; i < count; i++) {
44 printf("%s\n", words[i]);
45 }
46 for (int i = 0; i < count; i++) {
47 free(words[i]);
48 }
49 free(words);
50 return 0;
51 }
📝 此題為申論題,共 7 小題
小題 (七)
46~49 行程式碼功能(2 分)
思路引導
VIP
看到 free() 函數,第一直覺應聯想到與 malloc() 配對的動態記憶體釋放。接著對照程式碼前半段 words[i] 與 words 的配置位置,說明迴圈內外釋放的具體對象,並點出避免「記憶體洩漏 (memory leak)」的核心目的。
這段程式碼的功能為釋放程式執行期間動態配置的記憶體空間,以避免記憶體洩漏(Memory Leak)。詳細步驟包含:
(1) 第 46-48 行:利用迴圈將先前為儲存個別字串內容所動態配置的記憶體空間(words[i])逐一釋放。
(2) 第 49 行:釋放指標陣列本身(words)所使用的動態記憶體空間。
小題 (一)
6~12 行程式碼功能(4 分)
思路引導
VIP
看到此題,首先觀察函式接收兩個字元指標,且迴圈內透過解指標(*s1, *s2)逐一比對字元並遞增指標。最後回傳相異字元的差值,即可輕易辨識出這是 C 標準函式庫 strcmp(字串比較)的底層手動實作,作答時務必點出「字串比較」目的與「回傳值」代表的意義。
此段程式碼的功能為比較兩個字串的大小(等同於 C 標準函式庫中的 strcmp 函式)。
其運作機制與特徵如下:
- 逐字元比對:透過
while 迴圈逐一比較兩個字串 (s1 與 s2) 對應位置的字元,直到遇到不相同的字元,或遇到字串結束字元(\0)為止。
小題 (二)
13~17 行程式碼功能(4 分)
思路引導
VIP
考生看到這段程式碼,應首先分析傳入函式的參數型態與迴圈的終止條件。觀察 while (s[len]) 判斷式可知,當遇到字串結束字元 \0(數值為 0)時迴圈才會停止,透過變數 len 累加計算次數,便能推導出這是在實作計算字串長度的功能。
第 13~17 行程式碼實作了計算字串長度的功能,其作用等同於 C 標準函式庫中的 strlen() 函式。
其運作機制與特徵包含:
(1) 接受一個常數字元指標 s 作為傳入參數,並宣告變數 len 用於計數。
小題 (三)
19~29 行程式碼功能(7 分)
思路引導
VIP
遇到程式碼功能解釋題,先將程式碼依據『初始化、輸入處理、核心邏輯更新』等區塊進行拆解。接著逐行觀察變數狀態變化、系統呼叫(如 malloc, fgets)的用途,以及字串處理(如去換行)的細節,最後綜合成一個完整的功能描述。
【破題】
此段程式碼(第19至29行)的主要功能為:「從標準輸入逐行讀取字串,處理換行符號後,依據字串實際長度動態配置記憶體,並將其儲存於字元指標陣列中」。
【論述】
小題 (四)
30~32 行程式碼功能(2 分)
思路引導
VIP
看到這題,首先觀察 for 迴圈的邊界條件(走訪 count 次)與迴圈主體(printf 輸出)。接著回溯確認自訂函式 c2 的內部邏輯(透過 while 迴圈計算並回傳字串長度),結合參數 words[i],即可推導出整體程式碼的具體功能。
此段程式碼的功能為:依序印出陣列中所儲存的每一個字串,以及該字串的字元長度。
詳細說明:程式利用 for 迴圈走訪 words 陣列中所有已儲存的字串(共 count 個),並透過 printf 函式將目前的字串內容(words[i])與呼叫 c2 函式所計算出來的該字串長度(c2(words[i]))一併顯示於螢幕上。
小題 (五)
33~41 行程式碼功能(4 分)
思路引導
VIP
觀察巢狀迴圈與相鄰元素(words[j]與words[j+1])比較後交換位置的特徵,可直接判定為氣泡排序法(Bubble Sort)。接著分析比較條件 c1(...) > 0,確認 c1 功能類似 strcmp,即可推導出整體功能為對字串陣列進行字典序遞增排序。
【破題】此段程式碼的功能為實作「氣泡排序法(Bubble Sort)」,將字串陣列進行排序。
【論述】
一、演算法特徵:第 33~41 行使用了典型的兩層巢狀迴圈(外層控制回合數,內層走訪未排序元素),並在第 36~38 行透過暫存變數 temp 來對調相鄰的指標元素。
小題 (六)
42~45 行程式碼功能(2 分)
思路引導
VIP
先觀察第42行的提示字串,再檢視第43至45行的 for 迴圈結構與 printf 函式。由於前段程式碼(第33至41行)剛執行完氣泡排序,因此這段程式碼的目的顯然是將排序後的結果逐一輸出至螢幕。
此段程式碼的功能為依序印出完成排序後的字串陣列。
詳細說明:
第 42 行先印出提示訊息「Sorted words:」,接著第 43 至 45 行利用 for 迴圈逐一走訪 words 陣列(從索引 0 到 count-1),將經過字典序排序後的各個單字依次輸出至標準輸出(螢幕)。