112 地方特考三等 資訊處理類科 程式設計 考古題詳解

112 年・地方特考・三等・資訊處理類科
試題代碼 程式設計

第 一 題25 分

關於下列 C 程式碼,請說明程式執行後,程式碼編號 27~33 的輸出,以及其運算邏輯。

#include <stdio.h> #define SIZE 30

typedef enum direction { North, South, East=3, West } dir_t;

int f1(int a, int b) { int x = 3.0 / a; double y = (a/2) * (b%3) + x; return y; }

int f2(dir_t d) { d = (North+East)/2 > d ? East : West; return d; }

int f3(int a, int b) { if (b==a || b<=1) return a+b; else if (a<=1) return b-a; else return f3(a-b, a-1)+b+a; }

int f4(int a, int b) { int data[SIZE]; for (int i=1, k=0; i<a; i++) { if (i%2==0) data[k++]=i; } return data[b]; }

unsigned int f5(unsigned int a, unsigned int b) { return (~a&b); }

int main() { printf("%d\n", f1(10, 4)); printf("%d\n", f2(South)); printf("%d\n", f3(6, 4)); printf("%u\n", f3(7, 4)); printf("%d\n", f4(20, 5)); printf("%d\n", f4(10, 4)); printf("%u\n", f5(4, 7)); return 0; }

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題考查 C 語言的整數除法與型別轉換、列舉常數、遞迴、陣列索引,以及位元補數與位元運算。輸出依 main 中的呼叫順序,分別對應程式碼編號 27~33。

解題方法

  1. 程式碼編號 27:f1(10, 4)

a、b、x 都是 int。因此 3.0 / a 先以浮點數計算為 0.30.3,再轉成 int,小數部分截去,故 x=0。

在 (a/2) 中兩個運算元都是整數,因此 10/2=510/2=5;而 4%3=14\%3=1。所以:

y=5×1+0=5.0y=5\times1+0=5.0

return y 將 double 轉成 int,結果是 5。輸出:5。

  1. 程式碼編號 28:f2(South)

列舉值依宣告順序為:

North=0,South=1,East=3,West=4North=0,\quad South=1,\quad East=3,\quad West=4

因此 (North+East)/2 是 (0+3)/2=1(0+3)/2=1。條件 1 > d 對 d=South=1 不成立,故選擇 West,回傳 4。輸出:4。

  1. 程式碼編號 29:f3(6, 4)

遞迴規則是:若 b==a 或 b<=1,回傳 a+b;否則若 a<=1,回傳 b-a;其餘回傳 f3(a-b, a-1)+b+a。

f3(6,4)=f3(2,5)+4+6=f3(−3,1)+5+2+4+6=(−3+1)+5+2+4+6=15\begin{aligned} f3(6,4) &=f3(2,5)+4+6\\ &=f3(-3,1)+5+2+4+6\\ &=(-3+1)+5+2+4+6\\ &=15 \end{aligned}

第二層呼叫 f3(-3,1) 因 b<=1,直接回傳 −3+1=−2-3+1=-2。輸出:15。

  1. 程式碼編號 30:f3(7, 4)
f3(7,4)=f3(3,6)+4+7=f3(−3,2)+6+3+4+7\begin{aligned} f3(7,4) &=f3(3,6)+4+7\\ &=f3(-3,2)+6+3+4+7 \end{aligned}

在 f3(-3,2) 中,b==a 與 b<=1 均不成立,但 a<=1 成立,因此回傳 2−(−3)=52-(-3)=5。

f3(7,4)=5+6+3+4+7=25f3(7,4)=5+6+3+4+7=25

🔒

後續完整解題步驟與【答案】

免費註冊,享 3 天全站完整詳解閱覽。

免費註冊

第 二 題25 分

針對下列 C++ 程式,請標示出 Except 類別的 f1、⋯、f6 函式中有問題的函式,並說明其問題之原因;並請說明若將有問題的函式和程式碼刪除,其程式執行後之輸出。

#include <stdexcept> #include <iostream> #include <string> using namespace std;

class Except { public: void f1(int c); void f2(); void f3(); void f4(); void f5(); void f6(); };

int main() { Except e; e.f1(1); e.f2(); e.f3(); e.f4(); e.f5(); e.f6(); return 0; }

void Except::f1(int c) { if (c<0) throw out_of_range("large"); cout<<"exc1"<<endl; }

void Except::f2() { f1(-1); }

void Except::f3() { try { f1(-1); cout<<"ok"<<endl; } catch(exception &e) { cout<<"exc2"<<endl; } }

void Except::f4() { try { throw out_of_range("no"); } catch(out_of_range &e) { cout<<e.what()<<endl; cout<<"exc3"<<endl; } }

void Except::f5() { try { throw out_of_range("yes"); } catch(exception &e) { cout<<"exc41"<<endl; } catch(out_of_range &e) { cout<<e.what()<<endl; cout<<"exc42"<<endl; } }

void Except::f6() { try { throw out_of_range("ok"); } finally { cout<<"exc6"<<endl; } }

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題考 C++ 例外處理的基本規則:

  • throw 會將例外往呼叫堆疊外層傳遞,直到找到可處理該例外型別的 catch。若離開 main 時仍無人處理,程式會呼叫 std::terminate,不會繼續執行後續函式。
  • std::out_of_range 繼承自 std::exception,因此 catch(exception&) 可以捕捉 out_of_range。
  • 同一組 catch 子句要由較具體的型別排在較一般的型別之前;否則一般型別先捕捉後,後面的具體型別就無法接手。
  • C++ 沒有 finally 語法。這種語法常見於其他語言,不能直接用在 C++ 的 try 後面。

解題方法

逐一追蹤每個函式中的例外是否有相應的 catch,並確認例外是否能離開函式、一路傳到 main。若某函式有問題,依題意刪除該函式的定義及呼叫,再按剩餘呼叫順序列出輸出。

各函式判斷

f1:沒有問題

當 c < 0 時,執行 throw out_of_range("large");否則才輸出 exc1。函式本身可以拋出例外,呼叫端負責捕捉或讓例外繼續傳遞,這是合法的 C++ 寫法。

f2:有問題

f2 呼叫 f1(-1),因此 f1 拋出 out_of_range。f2 沒有捕捉例外,例外便繼續傳到 main。而 main 也沒有 try-catch,程式會在此終止,後續函式不會執行。

f3:沒有問題

f1(-1) 拋出的 out_of_range 會被 catch(exception &e) 捕捉,因為 out_of_range 是 exception 的衍

🔒

後續完整解題步驟與【答案】

免費註冊,享 3 天全站完整詳解閱覽。

免費註冊

第 三 題25 分

針對下列 Java 程式碼,請完成統一塑模語言(UML)類別圖 (a)~(e);另外請標示出錯誤程式碼行數並說明錯誤原因;以及說明若將錯誤行數程式碼予以註解後,執行其程式的輸出。

import java.io.*;

interface Pet { public abstract int eat(int f); };

class Dog implements Pet { public Dog(int f) { food = f; }

public int eat(int f) {
    food += f;
    return food;
}

private int food;

};

public class Main { public static void main(String[] args) { Pet d1 = new Pet(); Pet d2 = new Dog(); Pet d3 = new Dog(5); d1.eat(5); d2.eat(5); System.out.println("dog: "+d3.eat(5)); } }

UML 類別圖中的空格:

🖼️ 本題原卷含圖表。基於試題來源之版權考量,本站不轉載原卷影像; 題目文字已完整轉錄,圖表請自行參閱考選部公告之試題原檔。
這一題的完整詳解

核心觀念

本題考查 Java 介面、類別實作、建構子、封裝,以及 UML 類別圖表示法:

  • 介面以 <<interface>> 標示。
  • 類別實作介面,使用 UML「實作關係(realization)」表示:虛線加空心三角形,三角形指向介面。
  • public 在 UML 中以 + 表示,private 以 - 表示。
  • 方法格式通常寫成 + 方法名(參數名:型別):回傳型別。
  • 建構子名稱與類別相同,且沒有回傳型別。

UML 類別圖填答

(a) Pet 的類別/介面標示

<<interface>>

Pet 是介面,因此應在名稱 Pet 上方標示 <<interface>>。

(b) Pet 的方法

+ eat(f:int):int

原始宣告為:

public abstract int eat(int f);

因此:

  • public 對應 +
  • 參數 f 的型別為 int
  • 回傳型別為 int

介面方法也可用斜體表示其抽象性。

(c) Pet 與 Dog 之間的關係

實作關係(Realization)

UML 表示方式為:

  • 從 Dog 指向 Pet
  • 使用虛線
  • 線末端為空心三角形

因為程式碼為:

class Dog implements Pet

(d) Dog 的屬性

- food:int

原始宣告為:

private int food;

private 對應 UML 的 -。

(e) Dog 的方法

+ eat(f:int):int

原始方法為:

public int eat(int f)

圖中已列出的建構子若要完全依照程式碼,應為:

+ Dog(f:int)

因為程式只有:

public Dog(int f)

並沒有無參數建構子 Dog。因此圖中若印成 + Dog,該處的參數資訊是不完整或不正確的;空格 (e) 應填入 + eat(f:int):int。

錯誤程式碼行數與原因

第 15 行

🔒

後續完整解題步驟與【答案】

免費註冊,享 3 天全站完整詳解閱覽。

免費註冊

第 四 題25 分

針對下列 Python 程式碼,依序在兩個 Terminal 執行 server.py 和 client.py 後,在 client.py 輸入 Tom 和 quit;請說明 client.py 的 Terminal 之輸出內容,並說明 Line 03、04、05 程式碼的運作邏輯。

server.py:

server.py

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('127.0.0.1', 7000)) s.listen(5) print('wait for connection...')

while True: conn, addr = s.accept() print('connected by ' + str(addr)) indata = conn.recv(1024) print('recv: ' + indata.decode())

if 'quit' in indata.decode():
    outdata = 'bye'
else:
    outdata = 'hi ' + indata.decode()

conn.send(outdata.encode())
conn.close()

if 'quit' in indata.decode():
    break

print('listen...')

s.close()

client.py:

client.py

import socket

while True: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', 7000)) name = input('>name:') print('send:' + name) s.send(name.encode()) indata = s.recv(1024) s.close() print('>' + indata.decode())

if 'quit' in name:
    break

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題考查 TCP Socket 用戶端與伺服器端的基本通訊流程,以及字串、位元組資料的轉換:

  • socket.AF_INET 表示使用 IPv4;socket.SOCK_STREAM 表示使用 TCP。
  • send 傳送位元組資料,因此字串須先用 encode 編碼;recv 收到位元組資料,須用 decode 轉回字串。
  • accept 接受一個用戶端連線;close 關閉該次連線。
  • 伺服器收到 quit 後,回覆 bye,並結束伺服器的迴圈。

解題方法

依序追蹤每次迴圈中的執行順序:用戶端建立連線、讀取輸入、傳送資料、接收伺服器回覆,最後判斷是否輸入 quit。伺服器則對每次連線接收一筆資料、依內容回覆,若內容含有 quit,便離開伺服器迴圈。

第一次輸入:Tom

  1. 用戶端連線到伺服器,輸入 Tom。
  2. 用戶端印出 send:Tom,並傳送字串 Tom 編碼後的位元組。
  3. 伺服器收到資料,因為內容不含 quit,回覆 hi Tom。
  4. 用戶端收到回覆並關閉此次連線,印出 >hi Tom。
  5. 用戶端判斷 quit 不在 Tom 中,因此進入下一輪。

第二次輸入:quit

  1. 用戶端重新建立連線,輸入 quit。
  2. 用戶端印出 send:quit,並傳送資料。
  3. 伺服器收到資料,因為內容含有 quit,回覆 bye,接著關閉此次連線並跳出伺服器迴圈。
  4. 用戶端收到回覆並關閉此次連線,印出 >bye。
  5. 用戶端判斷 quit 在輸入內容中,因此跳出用戶端迴圈。

client.py Terminal 輸出

假設兩個 Terminal 均正常啟動,伺服器已在等待連線,且輸入內容恰為 Tom、quit,用戶端 Terminal 的輸出如下(輸入內容由使用者在提示符後輸入):

>name:Tom
send:Tom
>hi Tom
>name:quit
send:quit
>bye
🔒

後續完整解題步驟與【答案】

免費註冊,享 3 天全站完整詳解閱覽。

免費註冊

其他考古題