109 專技高考高等考試 資訊技師 程式設計 考古題詳解

109 年・專技高考・高等考試・資訊技師
試題代碼 程式設計

第 一 題25 分

請依據下列 C++ 程式碼執行後,試問輸出結果為何?

#include <stdio.h>

int F(int x, int y) { int c = 7; int d = c % 3; for (int i = 1; i <= y; i++) { d = c * (x - i + 1) / i; } return d; }

int main() { int h = 8; for (int a = h % 5 + 2; a > 3; a--) { for (int n = 0; n <= a; n++) { printf("%d", F(a, n)); } printf("\n"); } return 0; }

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

這一題的完整詳解

核心觀念

本題為典型的「程式追蹤題(Code Tracing)」,評量考生對 C/C++ 基礎語法與控制流程的掌握度,核心考點包含:

  1. 模數運算與運算子優先權:運算子 %(取餘數)與整數算術運算。
  2. 巢狀迴圈(Nested Loops)控制流程:外層與內層 for 迴圈的初始條件、終止條件與計數遞增/遞減。
  3. 區域變數賦值與迴圈覆蓋陷阱:在函式中,迴圈內每次迭代皆直接對變數 d 重新賦值(非累乘運算),前次計算結果會被覆蓋。
  4. 整數除法(Integer Division)特性:C/C++ 中兩整數相除採向零捨去(Truncation toward zero),小數部分直接捨棄。

解題方法

解題切入點分為「主程式外層流程分析」與「自訂函式 F(x, y) 運算化簡」兩大步驟。

步驟一:分析主程式 main 的迴圈範圍

  1. 外層迴圈變數 aa 的範圍:
  • 初始值:h=8h = 8,故 a=(h(mod5))+2=(8(mod5))+2=3+2=5a = (h \pmod 5) + 2 = (8 \pmod 5) + 2 = 3 + 2 = 5。
  • 終止條件:a>3a > 3;更新步進:a--。
  • 因此外層迴圈共執行 2 次,其值依序為:
  • 第一輪:a=5a = 5
  • 第二輪:a=4a = 4
  • 當 a=3a = 3 時不滿足 a>3a > 3,迴圈終止。
  1. 內層迴圈變數 nn 的範圍:
  • 條件為 for (int n = 0; n <= a; n++)。
  • 當 a=5a = 5 時:nn 依序為 0,1,2,3,4,50, 1, 2, 3, 4, 5(共 6 次呼叫)。
  • 當 a=4a = 4 時:nn 依序為 0,1,2,3,40, 1, 2, 3, 4(共 5 次呼叫)。
  1. 輸出格式:
  • 內層呼叫 printf("%d", F(a, n));,數值之間沒有空格。
  • 外層每輪結束印出換行字元 \n。

步驟二:分析自訂函式 F(x, y) 的運算通式

函式定義如下:

int F(int x, int y) {
 int c = 7;
 int d = c % 3;
 for (int i = 1; i <= y; i++) {
 d = c * (x - i + 1) / i;
 }
 return d;
}
  1. 初始值:c=7c = 7,d=7(mod3)=1d = 7 \pmod 3 = 1。
  2. 關鍵觀察:
  • 迴圈內部算式為 d = c * (x - i + 1) / i;。
  • 注意右式使用常數 c=7c = 7,而非累計變數 dd。因此每次迭代都在重新計算並直接覆蓋 dd 的值。
  • 當 y=0y = 0 時:迴圈條件 i <= 0 不成立,迴圈不執行,直接回傳初始值 d=1d = 1。
  • 當 y≥1y \ge 1 時:迴圈執行 i=1i = 1 至 i=yi = y,最終回傳的數值僅取決於最後一次迭代(即 i=yi = y 時): d=⌊7×(x−y+1)y⌋d = \left\lfloor \frac{7 \times (x - y + 1)}{y} \right\rfloor

步驟三:逐項代入推導輸出結果

1. 第一行輸出(a=5a = 5,n=0∼5n = 0 \sim 5):
  • n=0n = 0:迴圈未執行,回傳初始值 d=1d = 1。
  • n=1n = 1:i=1  ⟹  d=⌊7×(5−1+1)1⌋=7×51=35i = 1 \implies d = \lfloor \frac{7 \times (5 - 1 + 1)}{1} \rfloor = \frac{7 \times 5}{1} = 35。
  • n=2n = 2:i=2  ⟹  d=⌊7×(5−2+1)2⌋=7×42=14i = 2 \implies d = \lfloor \frac{7 \times (5 - 2 + 1)}{2} \rfloor = \frac{7 \times 4}{2} = 14。
  • n=3n = 3:i=3  ⟹  d=⌊7×(5−3+1)3⌋=7×33=7i = 3 \implies d = \lfloor \frac{7 \times (5 - 3 + 1)}{3} \rfloor = \frac{7 \times 3}{3} = 7。
🔒

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

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

免費註冊

第 二 題25 分

請依據下列 C++ 程式碼執行後,若輸入如下所示,試問輸出結果為何?

輸入:

1 3 5 7 2 4 6 8

#include <stdio.h>

void getMatrixElements(int matrix[][10], int row, int column) { int i, j;

printf("\nEnter elements: \n");

for (i = 0; i < row; ++i) {
    for (j = 0; j < column; ++j) {
        printf("Enter a%d%d: ", i + 1, j + 1);
        scanf("%d", &matrix[i][j]);
    }
}

}

void calMatrices( int first[][10], int second[][10], int result[][10], int r1, int c1, int r2, int c2 ) { int i, j, k;

for (i = 0; i < r1; ++i) {
    for (j = 0; j < c2; ++j) {
        result[i][j] = 0;
    }
}

for (i = 0; i < r1; ++i) {
    for (j = 0; j < c2; ++j) {
        for (k = 0; k < c1; ++k) {
            result[i][j] += first[i][k] * second[k][j];
        }
    }
}

}

void display(int result[][10], int row, int column) { int i, j;

printf("\nOutput Matrix:\n");

for (i = 0; i < row; ++i) {
    for (j = 0; j < column; ++j) {
        printf("%d  ", result[i][j]);

        if (j == column - 1) {
            printf("\n");
        }
    }
}

}

int main() { int first[5][5], second[5][5], result[5][5]; int r1 = 2, c1 = 2, r2 = 2, c2 = 2;

getMatrixElements(first, r1, c1);
getMatrixElements(second, r2, c2);
calMatrices(first, second, result, r1, c1, r2, c2);
display(result, r1, c2);

return 0;

}

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

這一題的完整詳解

核心觀念

  1. 二維陣列(Two-Dimensional Array)的函式傳遞與配置: 在 C/C++ 中,將多維陣列傳遞給函式時,除了第一維(列數)可省略外,第二維(行數,Column)的大小必須明確給定(例如 int matrix[][10]),編譯器才能依據列優先(Row-major order)計算位址位移量(Stride),其定址公式為: Address(A[i][j])=Base+(i×Column+j)×sizeof(type)\text{Address}(A[i][j]) = \text{Base} + (i \times \text{Column} + j) \times \text{sizeof}(\text{type})
  2. 巢狀迴圈(Nested Loops)與矩陣相乘演算法: 若矩陣 AA 維度為 r1×c1r_1 \times c_1、矩陣 BB 維度為 r2×c2r_2 \times c_2(必須滿足 c1=r2c_1 = r_2),相乘後的結果矩陣 CC 維度為 r1×c2r_1 \times c_2。三層巢狀迴圈的計算核心為: C[i][j]=∑k=0c1−1A[i][k]×B[k][j]C[i][j] = \sum_{k=0}^{c_1-1} A[i][k] \times B[k][j] 時間複雜度為 O(r1×c2×c1)O(r_1 \times c_2 \times c_1)。
  3. 格式化輸出與流程控制: printf 與 scanf 的格式控制符,包含空白字元(%d 後方具兩個空白)及換行字元(\n)的印出時機。

解題方法

步驟一:分析主程式變數初始化

main 函式中宣告了三個二維陣列 first、second、result,並設定維度參數:

  • r1=2,c1=2r_1 = 2, c_1 = 2(代表第一個矩陣為 2×22 \times 2)
  • r2=2,c2=2r_2 = 2, c_2 = 2(代表第二個矩陣為 2×22 \times 2)

步驟二:追蹤資料輸入函式 getMatrixElements

依據雙層迴圈順序(先列後行:i = 0, 1,j = 0, 1),輸入串流依序讀入數值:

  1. 讀入第一個矩陣 first(共 4 個數值:1, 3, 5, 7):
  • i=0,j=0  ⟹  first[0][0]=1i=0, j=0 \implies first[0][0] = 1
  • i=0,j=1  ⟹  first[0][1]=3i=0, j=1 \implies first[0][1] = 3
  • i=1,j=0  ⟹  first[1][0]=5i=1, j=0 \implies first[1][0] = 5
  • i=1,j=1  ⟹  first[1][1]=7i=1, j=1 \implies first[1][1] = 7

即第一個矩陣為: A=[1357]A = \begin{bmatrix} 1 & 3 \\ 5 & 7 \end{bmatrix}

  1. 讀入第二個矩陣 second(後續 4 個數值:2, 4, 6, 8):
  • i=0,j=0  ⟹  second[0][0]=2i=0, j=0 \implies second[0][0] = 2
  • i=0,j=1  ⟹  second[0][1]=4i=0, j=1 \implies second[0][1] = 4
  • i=1,j=0  ⟹  second[1][0]=6i=1, j=0 \implies second[1][0] = 6
  • i=1,j=1  ⟹  second[1][1]=8i=1, j=1 \implies second[1][1] = 8

即第二個矩陣為: B=[2468]B = \begin{bmatrix} 2 & 4 \\ 6 & 8 \end{bmatrix}

步驟三:計算矩陣相乘 calMatrices

  1. 先將 result 陣列前 2×22 \times 2 元素清為 0。
  2. 透過三層迴圈進行矩陣乘法 C=A×BC = A \times B:
  • result[0][0]=A[0][0]×B[0][0]+A[0][1]×B[1][0]=1×2+3×6=2+18=20result[0][0] = A[0][0] \times B[0][0] + A[0][1] \times B[1][0] = 1 \times 2 + 3 \times 6 = 2 + 18 = 20
  • result[0][1]=A[0][0]×B[0][1]+A[0][1]×B[1][1]=1×4+3×8=4+24=28result[0][1] = A[0][0] \times B[0][1] + A[0][1] \times B[1][1] = 1 \times 4 + 3 \times 8 = 4 + 24 = 28
  • result[1][0]=A[1][0]×B[0][0]+A[1][1]×B[1][0]=5×2+7×6=10+42=52result[1][0] = A[1][0] \times B[0][0] + A[1][1] \times B[1][0] = 5 \times 2 + 7 \times 6 = 10 + 42 = 52
🔒

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

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

免費註冊

第 三 題25 分

請依據下列 C++ 程式碼執行後,回答輸出結果為何?

#include <stdio.h>

struct EmpAddress { char *ename; char stname[20]; int pincode; } employee1 = {"John Alter", "Court Street", 654134}, *pt1 = &employee1;

int main() { struct EmpAddress employee2 = {"Bob Hard", "First Street", 462524}, employee3 = {"Draven Green", "Darkest Street", 883126}; struct EmpAddress *pt2, *pt3;

pt2 = &employee2;
pt3 = &employee3;

pt2->ename = pt1->ename;
pt2->pincode = 315948;
pt1 = pt2;
strcpy(pt3->stname, "Love Street");
pt1->ename = pt3->ename;

printf(" %s from %s, pincode:%d \n\n",
       pt1->ename, (*pt1).stname, pt1->pincode);
printf(" %s from %s, pincode:%d \n\n",
       pt2->ename, (*pt2).stname, pt2->pincode);
printf(" %s from %s, pincode:%d \n\n",
       pt3->ename, (*pt3).stname, pt3->pincode);

return 0;

}

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

這一題的完整詳解

核心觀念

本題評量 C/C++ 程式設計中結構體(struct)、指標操作(Pointers)與字串處理的綜合追蹤能力,涉及以下四大核心觀念:

  1. 結構體成員存取運算子:
  • 箭號運算子 ->:透過結構體指標存取成員,語法等價於 (*ptr).member。
  • 點運算子 .:直接透過結構體實體變數存取成員。
  1. 指標賦值(Pointer Aliasing)與對象重導向:
  • 當執行指標變數之間的賦值(如 pt1=pt2pt1 = pt2)時,改變的是「指標所儲存的記憶體位址」,而非複製結構體內容。此後 pt1pt1 與 pt2pt2 指向同一個結構體實體,修改 pt1pt1 所指內容等同於修改 pt2pt2 所指內容。
  1. 字串指標與字元陣列之賦值差異:
  • char *ename 為字元指標,執行 ename = ... 僅改變指標指向的字串常值(String Literal)記憶體位址(Shallow Copy)。
  • char stname[20] 為字元陣列,不可直接用等號賦值,須使用 strcpy 將字串內容逐字複製進陣列記憶體空間(Deep Copy)。
  1. printf 格式化輸出控制:
  • 格式字串 " %s from %s, pincode:%d \n\n" 最前方包含一個半形空格,結尾包含兩個換行符號(\n\n),輸出行之間會產生空行。

解題方法

採用「記憶體狀態追蹤法(Memory Tracing)」,先確立初始狀態,再逐行追蹤變數數值的變動。

1. 初始狀態分析

程式配置了三個結構體變數與三個結構體指標:

變數名稱實體類型ename 指向stname 內容pincode 數值指標變數指向
employee1全域變數"John Alter""Court Street"654134654134pt1→employee1pt1 \to \text{employee1}
employee2區域變數"Bob Hard""First Street"462524462524pt2→employee2pt2 \to \text{employee2}
employee3區域變數"Draven Green""Darkest Street"883126883126pt3→employee3pt3 \to \text{employee3}

2. 逐行執行推導

  1. pt2->ename = pt1->ename;
  • pt2pt2 指向 employee2,pt1pt1 指向 employee1。
  • 將 employee1.ename 的位址複製給 employee2.ename。
  • 此時 employee2.ename 改指向 "John Alter"。
  1. pt2->pincode = 315948;
  • 將 employee2.pincode 修改為 315948315948。
  1. pt1 = pt2;(關鍵步驟)
  • 指標重新賦值:將 pt2pt2 儲存的位址賦予 pt1pt1。
  • pt1pt1 不再指向 employee1,改為與 pt2pt2 同時指向 employee2。
🔒

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

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

免費註冊

第 四 題25 分

請依據下列 C++ 程式碼執行後,若輸入如下所示,試問輸出結果為何?

輸入:

136631

#include <stdio.h>

int main() { int n, rN = 0, remainder, originalN, flag = 0, num = 0, i;

printf("Enter an integer: ");
scanf("%d", &n);

originalN = n;

while (n != 0) {
    remainder = n % 10;
    rN = rN * 10 + remainder;
    n /= 10;
    num++;
}

if (originalN == rN) {
    printf("True\n");
    flag = 1;
} else {
    printf("False\n");
    flag = 0;
}

n = originalN;
rN = 0;
num = num * 2;

if (flag == 1) {
    while (n != 0) {
        remainder = n % 10;
        rN = rN + remainder;
        printf("%d\n", rN);
        n /= 10;
    }
} else {
    printf("%d\n", rN);
}

return 0;

}

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

這一題的完整詳解

核心觀念

本題為典型的「程式追蹤題(Code Tracing)」,主要測驗考生對 C/C++ 語言基礎語法、控制結構與常見演算法模板的掌握程度,核心觀念包含:

  1. 數值拆解運算:利用模除運算子 % 10 依序取得最低有效位數(LSD, Least Significant Digit),搭配整數除法運算子 / 10 去除已處理位數,達到由右至左遍歷十進位數字每一位的效果。
  2. 數字反轉與迴文數(Palindrome Number)檢驗:透過公式 rN=rN×10+remainderrN = rN \times 10 + remainder 重構反轉數值,並藉由比對原始數值 originalNoriginalN 與反轉值 rNrN 是否相等,判定是否為迴文數。
  3. 流程控制與狀態旗標:利用變數 flag 記錄判斷結果,並引導後續的分支走向。
  4. 位數前綴累加(Prefix Sum)與迴圈輸出:在第二個迴圈中,利用 rN=rN+remainderrN = rN + remainder 由低位向高位逐步累加各個位數的數值,且在每次迭代過程中即時輸出累加值。

解題方法

本程式可分為三大階段進行追蹤:

  • 階段一:提示輸入與反轉迴文判定
  • 階段二:變數重設與分支轉移
  • 階段三:各數位累加與逐行輸出

輸入值為:136631

階段一:反轉迴文判定追蹤

程式起始先印出提示訊息,讀入整數並備份:

  • 執行 printf("Enter an integer: ");,輸出提示字串(結尾無換行符號 \n)。
  • 讀入 n=136631n = 136631,設定 originalN=136631originalN = 136631,rN=0rN = 0,num=0num = 0。

進入第一個 while (n != 0) 迴圈,每次擷取個位數進行反轉重組:

迭代次數進入時 nnremainder = n % 10rN = rN * 10 + remainder離開時 n=n/10n = n / 10num++
第 1 次136631136631110×10+1=10 \times 10 + 1 = 1136631366311
第 2 次1366313663331×10+3=131 \times 10 + 3 = 131366136622
第 3 次136613666613×10+6=13613 \times 10 + 6 = 13613613633
第 4 次13613666136×10+6=1366136 \times 10 + 6 = 1366131344
第 5 次1313331366×10+3=136631366 \times 10 + 3 = 136631155
第 6 次111113663×10+1=13663113663 \times 10 + 1 = 1366310066

迴圈結束時:n=0n = 0,rN=136631rN = 136631,num=6num = 6。

執行條件判斷:

  • if (originalN == rN):比對 136631==136631136631 == 136631,條件成立。
  • 印出 True\n,並將 flag 設為 11。

階段二:變數重設

接續執行:

  • n = originalN; →n=136631\rightarrow n = 136631
  • rN = 0; →rN\rightarrow rN 歸零,作為後續累加器使用。
  • num = num * 2; →num=6×2=12\rightarrow num = 6 \times 2 = 12(此處為干擾運算,後續未再使用 num)。

階段三:各數位累加輸出追蹤

因為 flag == 1,程式進入 if (flag == 1) 內部之 while (n != 0) 迴圈:

🔒

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

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

免費註冊

其他考古題