---
# System prepended metadata

title: APCS 2017-03-04 觀念題 詳解
tags: [APCS]

---

# APCS 2017-03-04 觀念題 詳解

###### tags: `APCS`

[APCS 模擬試卷 2017-03-04 觀念題](https://apcs.csie.ntnu.edu.tw/wp-content/uploads/2018/12/1060304APCSconcept.pdf)的詳解。

## 第 1 題

此函式使用了二分搜尋法，可以在已排序的陣列中找到「大於 `x` 的最小值」。然而這個函式沒有進行例外處理 (exception handling)，它沒有考慮到如果給定的 `x` 已經大於陣列中的最大值時，不可能可以找到「大於 `x`」 的數字。因此，如果傳入一個大於陣列中最大值的數字時，函式只會回傳陣列當中的最大值，並不滿足「**大於 `x` 的**最小值」這樣的條件，因此答案為 (D) 選項。

## 第 2 題

`A1` 和 `A2` 都用到了 `F`， 所以必須先拆解 `F` 看看他會做什麼。

`F` 是一個遞迴函式，他會先印出 `x` 個星星，再執行 `F(x / 2)` 兩次，因此我們可以用以下遞迴式計算 `F(x)` 會印出的星星數量： $$F(x) = x + F(\lfloor\frac{x}{2}\rfloor) \times 2$$ 要注意的是，此處的除法都是指整數除法（因為 `x` 被宣告為 `int`）， 因此除法的結果只取商，也就是無條件捨去的除法。所以上方式子中的 $\frac{x}{2}$ 必須加上下高斯符號。

依照上式，我們可以手動算出 `F(x)` 在不同參數時會印出的星星數量

```
F(1) = 1
F(2) = 2 + F(1) * 2 = 2 + 1 * 2 = 4
F(3) = 3 + F(1) * 2 = 3 + 1 * 2 = 5
F(4) = 4 + F(2) * 2 = 4 + 4 * 2 = 12
F(5) = 5 + F(2) * 2 = 5 + 4 * 2 = 13
F(6) = 6 + F(3) * 2 = 6 + 5 * 2 = 16
F(7) = 7 + F(3) * 2 = 7 + 5 * 2 = 17
F(8) = 8 + F(4) * 2 = 8 + 12 * 2 = 32
F(9) = 9 + F(4) * 2 = 9 + 12 * 2 = 33
F(10) = 10 + F(5) * 2 = 10 + 13 * 2 = 36
F(11) = 11 + F(5) * 2 = 11 + 13 * 2 = 37
F(12) = 12 + F(6) * 2 = 12 + 16 * 2 = 44
...
```

接著回來看 `A1` 和 `A2`， 我們會發現 `A1` 和 `A2` 都是呼叫了 `F` 兩次，但參數有所不同。現在我們已經知道 `F` 在帶入不同數字時會印出多少星星了，因此就不難求出 `A1` 和 `A2` 會印出幾個星星。

* (A) 選項
    * `A1(5) = F(1) + F(4) = 1 + 12 = 13`
    * `A2(5) = F(2) + F(3) = 4 + 5 = 9`
    * `A1(5) > A2(5)`， 此選項正確
* (B) 選項
    * `A1(13) = F(2) + F(10) = 4 + 36 = 40`
    * `A2(13) = F(5) + F(7) = 13 + 17 = 30`
    * `A1(13) > A2(13)`， 此選項正確
* \(C\) 選項
    * `A1(14) = F(2) + F(11) = 4 + 37 = 41`
    * `A2(14) = F(5) + F(8) = 13 + 32 = 47`
    * `A2(14) > A1(14)`， 此選項正確
* (D) 選項
    * `A1(15) = F(3) + F(12) = 5 + 44 = 49`
    * `A2(15) = F(6) + F(9) = 16 + 33 = 49`
    * `A1(15) = A2(15)`， 此選項錯誤

因此答案為 (D) 選項。

## 第 3 題

此題同樣是考遞迴概念，直接將各選項代入觀察輸出值即可。

* (A) 選項
    * `F(14) = 14 * F(13) = 14 * 13 * F(12) = ... = 14 * 13 * 12 * ... * 3 != 40`
* (B) 選項
    * `F(14) = 14 + F(11) = 14 + 11 + F(8) = ... = 14 + 11 + 8 + 5 + 2 == 40`
* \(C\) 選項
    * `F(14) = 14 - F(12) = 14 - (12 - F(10)) = ... = 14 - 12 + 10 - 8 + 6 - 4 + 2 != 40`
* (D) 選項
    * 語法錯誤 （應為 `F(3 * n + 1)`）

因此答案為 (B) 選項。

## 第 4 題

本題的觀念為輾轉相除法，請自行參閱[維基百科的說明頁面](https://zh.wikipedia.org/zh-tw/%E8%BC%BE%E8%BD%89%E7%9B%B8%E9%99%A4%E6%B3%95)。

## 第 5 題

此段程式碼同時進行了兩個線性搜尋： `p` 是用來尋找陣列中的最大值； `q` 則是用來搜尋陣列中最小值。兩者皆以第一個元素為比大小的基準，然後看過剩下的 `n - 1` 個元素，遇到比當前記錄的值更大 / 更小的值時就取代掉當前值。因此，選項 (A), (B) 的敘述無誤。

但是題目並沒有保證 `A` 當中的數字不會重複， 如果我在陣列中存入 `n` 個一樣的數字，那麼最大值就會等於最小值，因此 \(C\) 選項不一定會成立。反之， (D) 選項有考慮到最大值可能大於，或是等同於第一個值的情況，因此絕對是正確的。

綜合以上分析，因此答案為 \(C\) 選項。

## 第 6 題

此段程式碼的 `rowsum` 是想要用來代表每一列的總和，那麼初始化（設定為 0） 的動作就必須要在每一行開始加總前進行，而不是在整個函式中只初始化一次。如果按照當前寫法， `rowsum` 鎂一次被印出時，印出的值會是「第 j 列**以前**的所有列中的數字總和」，而不是「第 j 列的數字總和」。除此之外，本函式並沒有語法上的錯誤或是會造成 runtime error 的錯誤，因此答案為 (A) 選項。

## 第 7 題

此段程式碼會以[巴斯卡三角形](https://zh.wikipedia.org/wiki/%E6%9D%A8%E8%BE%89%E4%B8%89%E8%A7%92%E5%BD%A2)的方式計算組合數 $C^n_k$。

```
B(5, 2) = B(4, 1)                               + B(4, 2)
        = B(3, 0) + B(3, 1)                     + B(3, 1)                     + B(3, 2)
        = 1       + B(2, 0) + B(2, 1)           + B(2, 0) + B(2, 1)           + B(2, 1)           + B(2, 2)
        = 1       + 1       + B(1, 0) + B(1, 1) + 1       + B(1, 0) + B(1, 1) + B(1, 0) + B(1, 1) + 1
        = 1       + 1       + 1       + 1       + 1       + 1       + 1       + 1       + 1       + 1
```

最後有 10 個 1， 因此會印出 10 次。

或者說，用巴斯卡三角形算組合數的時候，所有數字都是由邊邊上的 1 堆出來的，所以直接算 $C^5_2 = 10$， 即可得知會印出 10 次，因此答案為 (D) 選項。

## 第 8 題

拆解程式執行順序如下：

```
(global) s = 1;
printf("%d,", s); // 1,

// a = 1， 執行迴圈
(local) s = 6;
printf("%d,", s); // 6,
(local) s++;
printf("%d,", s); // 7,
// a = 0， 執行迴圈
printf("%d,", s); // 7,
(local) s++;
printf("%d,", s); // 8,
// a = -1， 結束迴圈

(global) s = 1;
printf("%d,", s); // 1,
(global) s = 9;
printf("%d", s);  // 9
```

同樣名字的區域變數會遮蔽掉全域變數，因此在 `add` 函式中所有對 `s` 的運算以及印出的 `s` 值指的都是 `add` 函式內的 `s`， 不是全域的 `s`。

同時， C 語言在傳入 `int` 型態的參數時採用的是 call by value 的策略，因此全域 `s` 被傳入 `add`  中當作 `a` 時，在 `add` 裏面對 `a` 的運算並不會改變全域 `s` 原本的值。因此，在 `add` 函式返回後， 全域 `s` 的值仍舊是 1。

而在 main function 中因為沒有別的叫作 `s` 的變數了，因此在 main function 中改變 `s` 的值時，變更的會是全域 `s` 的值。

綜合以上分析，可以得知印出的數列為 `1,6,7,7,8,1,9` 答案為 (B) 選項。

## 第 9 題

此段程式碼會將輸入的數字依序存入 `X[2]`, `X[3]`, `X[4]`, `X[5]`, `X[6]`, `X[7]`, `X[8]`, `X[9]`, `X[0]`, `X[1]` 中。 如果輸入依序是 `0 1 2 3 4 5 6 7 8 9` 的話，那麼

```
X[2] X[3] X[4] X[5] X[6] X[7] X[8] X[9] X[0] X[1]
  0    1    2    3    4    5    6    7    8    9
```

等同於

```
X[0] X[1] X[2] X[3] X[4] X[5] X[6] X[7] X[8] X[9]
  8    9    0    1    2    3    4    5    6    7
```

因此答案為 (D) 選項。

## 第 10 題

`K` 函式的行為在傳入的參數不同時有不同行為：

* 當傳入的參數除以 4 餘 0 時，他只會做 1 次的 `n = n + 1`
* 當傳入的參數除以 4 餘 1 時，他會透過遞迴呼叫做 4 次的 `n = n + 1`
* 當傳入的參數除以 4 餘 2 時，他會透過遞迴呼叫做 3 次的 `n = n + 1`
* 當傳入的參數除以 4 餘 3 時，他會透過遞迴呼叫做 2 次的 `n = n + 1`

`M` 函式透過迴圈呼叫了 100 次的 `K`， 傳入的參數當中，除以 4 餘 0、 餘 1、 餘 2、 餘 3 的分別有 25 個，因此 `n` 會被增加 $25 \times 1 + 25 \times 4 + 25 \times 3 + 25 \times 2 = 250$ 次，最後 `n` 的值會是 250， 答案為 (D) 選項。

## 第 11 題

* (A)選項
    * `A[1] = A[2];` 此時 `A[1]` 的值已經是 `A[2]` 的值
    * `A[2] = A[1];` 用 `A[2]` 的值覆蓋掉 `A[2]`
    * 最後 `A[1]`, `A[2]` 的值都是 `A[2]` 原本的值
* (B)選項
    * `A[3] = A[1];` 使用 `A[3]` 當作暫存空間，儲存 `A[1]` 原本的值
    * `A[1] = A[2];` 由於 `A[1]` 的值已經借放在 `A[3]` 了，所以可以放心的用 `A[2]` 的值覆蓋掉
    * `A[2] = A[3];` 把 `A[1]` 原本的值放入 `A[2]` 中
    * 成功交換了 `A[1]` 和 `A[2]` 中的值
* \(C\)選項
    * `A[2] = A[1];` 將 `A[1]` 的值存入 `A[2]`
    * `A[3] = A[2];` 將 `A[2]` 的值，也就是原本 `A[1]` 的值存入 `A[3]`
    * `A[1] = A[3];` 用 `A[1]` 的值覆蓋掉 `A[1]`
    * 最後 `A[1]`, `A[2]`, `A[3]` 的值都是 `A[1]` 原本的值
* (D)選項
    * 只有 (B) 是對的

因此答案為 (B) 選項。

## 第 12 題

此題的要求是「產生在 $[100, 1000]$ 範圍內的亂數」， 1000 - 100 + 1 = 901， 我們可以得知在這個範圍內總共有 901 種數字。將 `rand()` 的輸出除以 901 取餘數，可以得到餘數的範圍在 $[0, 900]$， 總共也是 901 種數字，但是跟需要的範圍差了 100 的 bias， 因此需要再往右位移 100， 也就是加上 100 的意思。總結以上， `rand() % 901 + 100` 產生出來的數字範圍就會落在 $[100, 1000]$ 的範圍內，答案為 (D) 選項。

題外話，雖然題目有說 `rand（）` 產生出的亂數範圍在 $[0, 10000]$， 總共有 10001 種數字。但我們需要的只有 901 種數字，所以只要 `rand()` 可以產生大於 901 種數字，無論範圍在哪裡其實都無所謂。

## 第 13 題

此段程式碼的迴圈在 `i` 值為 0, 5, 10, 15, ..., 95, 100 時會執行迴圈本體，總共會執行 21 次（因為 0, 5, ..., 100 共有 21 個數字）。

* (A) 選項
    * 如果上界改為 20 （沒有等於），且每次只 +1 的話，那麼在 `i` 值為 0, 1, 2, ..., 19 時會執行迴圈本體，總共會執行 20 次
* (B) 選項
    * 如果將初始值設定為 5， 那麼在 `i` 值為 5, 10, 15, ..., 100 時會執行迴圈本體，總共會執行 20 次
* \(C\) 選項
    * 如果上界改為 100 （沒有等於），那麼在 `i` 值為 0, 5, 10, 15, ..., 95 時會執行迴圈本體，總共會執行 20 次
* (D) 選項
    * 如果將初始值設定為 5， 且上界改為 100 （沒有等於）的話，那麼在 `i` 值為 5, 10, 15, ..., 95 時會執行迴圈本體，總共只會執行 **19** 次

因此答案為 (D) 選項。

## 第 14 題

分析程式執行的順序：

```c=
F(15);

// F(15)
printf ("%d\n" , 15);
return F(76); // (15 % 2 == 1) && (15 > 1)

// F(76)
printf ("%d\n" , 76);
return F(38); // (76 % 2 == 0)

// F(38)
printf ("%d\n" , 38);
return F(19); // (38 % 2 == 0)

// F(19)
printf ("%d\n" , 19);
return F(96); // (19 % 2 == 1) && (19 > 1)

// F(96)
printf ("%d\n" , 96);
return F(48); // (96 % 2 == 0)

// F(48)
printf ("%d\n" , 48);
return F(24); // (48 % 2 == 0)

// F(24)
printf ("%d\n" , 24);
return F(12); // (24 % 2 == 0)

// F(12)
printf ("%d\n" , 12);
return F(6); // (12 % 2 == 0)

// F(6)
printf ("%d\n" , 6);
return F(3); // (6 % 2 == 0)

// F(3)
printf ("%d\n" , 3);
return F(16); // (3 % 2 == 1) && (3 > 1)

// F(16)
printf ("%d\n" , 16);
return F(8); // (16 % 2 == 0)

// F(8)
printf ("%d\n" , 8);
return F(4); // (8 % 2 == 0)

// F(4)
printf ("%d\n" , 4);
return F(2); // (4 % 2 == 0)

// F(2)
printf ("%d\n" , 2);
return F(1); // (2 % 2 == 0)

// F(1)
printf ("%d\n" , 1);
// (1 % 2 == 1) but !(1 > 1), and !(1 % 2 == 0), no action
```

總共印出了 15 行的數字，答案為 (D) 選項。

## 第 15 題

```c=
void F (int a) {
    while (a < 10)
        a = a + 5;
    if (a < 12)
        a = a + 2;
    if (a <= 11)
        a = 5;
}
```

1. 在 `a < 10` 的情況下，會藉由第 2 行的 `while` 迴圈將 `a` 加到大於 10。 所以
    1. 與 5 同餘 1 的數字（如 6, 1, -4, ...） 會變成 11
    2. 與 5 同餘 2 的數字（如 7, 2, -3, ...） 會變成 12
    3. 與 5 同餘 3 的數字（如 8, 3, -2, ...） 會變成 13
    4. 與 5 同餘 4 的數字（如 9, 4, -1, ...） 會變成 14
    5. 可以被 5 整除的數字（如 5, 0, -5...） 會變成 10
2. 在 `a == 10` 或 `a == 11`， 以及 1.1 和 1.5 的情況下，第 4 行的 `if` 本體將會把 `a` 改動成 12 或 13， 因此無法進入第 6 行的 `if` 本體
3. 在 `a >= 12`， 以及 1.2, 1.3, 1.4 的情況下，第 4 行與第 6 行的 `if` 本體都不會被執行

以上的分析涵蓋了完整的整數範圍。由此可知，無論傳入的 `a` 是多少，永遠都不會進入第 6 行的 `if` 本體，因此 `a = 5` 永遠都不會被執行到，答案為 \(C\) 選項。

## 第 16 題

`F(7)` 回傳值為 17， 表示是從 `a * 2 + 3` 計算得來的；而 `F(8)` 回傳值為 25， 表示是從 `a * 3 + 1` 計算得來的。因此， `if` 中的條件判斷式必須是 7 可以滿足 （結果為 `true`）， 但 8 無法滿足 （結果為 `false`） 的條件。

* (A) 選項
    * `7 % 2 != 1` 的結果為 `false`
    * `8 % 2 != 1` 的結果為 `true`
* (B) 選項
    * `7 * 2 > 16` 的結果為 `false`
    * `8 * 2 > 16` 的結果為 `false`
* \(C\) 選項
    * `7 + 3 < 12` 的結果為 `true`
    * `8 + 3 < 12` 的結果為 `true`
* (D) 選項
    * `7 * 7 < 50` 的結果為 `true`
    * `8 * 8 < 50` 的結果為 `false`

因此答案為 (D) 選項。

## 第 17 題

```c=
int F (int n) {
    int x = 0;
    for (int i = 1; i <= n; i = i + 1)
        for (int j = i; j <= n; j = j + 1)
            for (int k = 1; k <= n; k = k * 2)
                x = x + 1;
    return x;
}
```

迴圈的執行必須從最內層分析到最外層。因此我們從第 5 行的迴圈開始看起：

0. `x` 從 0 開始累加
1. 第 5 行的迴圈每執行一次， `x` 就會增加 1
2. 第 5 行的迴圈每執行一次， `k` 就會變成原本的 2 倍，直到 `k` 超越 `n`， 才會停止執行迴圈。 `k` 一開始的值是 1，因此我們可以代入幾個 `n` 值推論第 5 行迴圈的執行次數
    * $n \leq 1$ 時，迴圈只會執行 1 次
    * $2 \leq n < 4$ 時，迴圈會執行 2 次（在這個範圍內的 `n`， 取 $log_2$ 後無條件進位，都會是 2）
    * $4 \leq n < 8$ 時，迴圈會執行 3 次（在這個範圍內的 `n`， 取 $log_2$ 後無條件進位，都會是 3）
    * $8 \leq n < 16$ 時，迴圈會執行 4 次（在這個範圍內的 `n`， 取 $log_2$ 後無條件進位，都會是 4）
    * ...
    * $2^{N - 1} \leq n < 2^N$ 時，迴圈會執行 $N$ 次（在這個範圍內的 `n`， 取 $log_2$ 後無條件進位，都會是 $N$）
    也就是說，將傳入的 `n` 取 $log_2$ 後無條件進位，就是第 5 行迴圈的執行次數，即第 5 行迴圈會執行 $\lfloor log_2n + 1 \rfloor$ 次
3. 第 4 行迴圈每執行一次， `x` 就會增加 $\lfloor log_2n + 1 \rfloor$。 第 4 行迴圈的執行次數是由第 3 行迴圈的 `i` 所決定的：
    * 當 `i == 1` 時，第 4 行迴圈會執行 `n` 次
    * 當 `i == 2` 時，第 4 行迴圈會執行 `n - 1` 次
    * 當 `i == 3` 時，第 4 行迴圈會執行 `n - 2` 次
    * 當 `i == 4` 時，第 4 行迴圈會執行 `n - 3` 次
    * ...
    * 當 `i == n` 時，第 4 行迴圈會執行 1 次
    因此，第 3, 4 行的雙層迴圈總共會執行 $1 + 2 + 3 + ... + n = \sum\limits_{i=1}^{n} i = \frac{n(n + 1)}{2}$ 次

因此，這三層迴圈總共會執行 $n(n + 1)\lfloor log_2n + 1 \rfloor/2$ 次，答案為 \(C\) 選項。

## 第 18 題

分析每次迴圈本體執行時 `i`, `j` 的值為：

```
i = 1, j = 1: (i + j) == 2, x = x + 2 = 2
i = 1, j = 2: (i + j) == 3, x = x + 3 = 5
i = 1, j = 3: (i + j) == 4, x = x + 4 = 9
i = 1, j = 4: (i + j) == 5
i = 1, j = 5: (i + j) == 6

i = 2, j = 1: (i + j) == 3, x = x + 3 = 12
i = 2, j = 2: (i + j) == 4, x = x + 4 = 16
i = 2, j = 3: (i + j) == 5
i = 2, j = 4: (i + j) == 6
i = 2, j = 5: (i + j) == 7

i = 3, j = 1: (i + j) == 4, x = x + 4 = 20
i = 3, j = 2: (i + j) == 5
i = 3, j = 3: (i + j) == 6
i = 3, j = 4: (i + j) == 7
i = 3, j = 5: (i + j) == 8

i = 4, j = 1: (i + j) == 5
i = 4, j = 2: (i + j) == 6
i = 4, j = 3: (i + j) == 7
i = 4, j = 4: (i + j) == 8
i = 4, j = 5: (i + j) == 9

i = 5, j = 1: (i + j) == 6
i = 5, j = 2: (i + j) == 7
i = 5, j = 3: (i + j) == 8
i = 5, j = 4: (i + j) == 9
i = 5, j = 5: (i + j) == 10
```

因此輸出為 20， 答案為 (D) 選項。

## 第 19 題

```c=
int main () {
    int M = -1, N = 101, s = 3;
    int A[] = ______?______;

    for (int i = 0; i < s; i = i + 1) {
        if (A[i] > M) {
            M = A[i];
        }
        else if (A[i] < N) {
            N = A[i];
        }
    }

    printf("M = %d, N = %d\n", M, N);

    return 0;
}
```

此段程式碼的錯誤點在於： 第 9 行是 `else if` 而不是 `if`， 這會造成 `A[i] < N` 只有在 `A[i] > M` 不成立的情況下才會執行。如果這個陣列是嚴格遞增的陣列（也就是每一個數字都比前面的數字還要大），那麼每一次進入迴圈 `A[i] > M` 永遠都會成立，第 9 行也就永遠都不會被執行到，也就是永遠都不會找到最小值 `N`。 因此答案為 (B) 選項。

## 第 20 題

```c=
int g1 = 30, g2 = 20;

int f1(int v) {
    int g1 = 10;
    return g1 + v;
}

int f2(int v) {
    int c = g2;
    v = v + c + g1;
    g1 = 10;
    c = 40;
    return v;
}

int main() {
    g2 = 0;
    g2 = f1(g2);
    printf("%d", f2(f2(g2)));
    return 0;
}
```

程式從 16 行開始執行，分析程式執行順序如下：

1. 由於 main function 內沒有定義叫作 `g2` 的變數，因此第 17 行的 `g2` 指的是第 1 行的全域變數 `g2`。 第 17 行會將該全域變數設定為 0
2. 第 18 行呼叫 `f1(g2)`，此時 `g2 == 0`， 也就是呼叫 `f1(0)`：
    1. 進入 `f1`， 第 4 行宣告了一個叫作 `g1` 的區域變數，其值為 10。 由於同名的區域變數會覆蓋掉全域變數，因此第 1 行的全域變數 `g1` 其值不會受影響
    2. 第 5 行回傳區域變數 `g1` 加上傳入參數 `v` 的值，也就是回傳 `10 + 0 = 10`
    3. 回到第 18 行，此時全域變數 `g2` 被設定為 10
3. 第 19 行呼叫 `f2(f2(g2))`， 此時全域變數 `g2` 為 10， 也就是 `f2(f2(10))`：
    1. 先解析內層的 `f2(10)`：
        1. 第 9 行宣告區域變數 `c`， 並以全域變數 `g2` 賦值。此時 `g2 = 10`， 因此 `c = 10`
        2. 第 10 行將傳入的參數 `v` 設定為 `v + c + g1`， 此時全域變數 `g1` 為 30， 因此 `v = 10 + 10 + 30 = 50`
        3. 由於 `f2` 內沒有定義叫作 `g1` 的變數，因此第 11 行的 `g1` 指的是第 1 行的全域變數 `g1`。 第 11 行會將該全域變數設定為 10
        4. 第 12 行將區域變數 `c` 設定為 40。 但因為回傳前都沒有再用到了，所以沒有影響
        5. 回傳 `v`， 也就是回傳 50
    2. 回到第 19 行，此時要解析外層的 `f2(50)`
        1. 第 9 行宣告區域變數 `c`， 並以全域變數 `g2` 賦值。此時 `g2 = 10`， 因此 `c = 10`
        2. 第 10 行將傳入的參數 `v` 設定為 `v + c + g1`， 此時全域變數 `g1` 為 10， 因此 `v = 50 + 10 + 10 = 70`
        3. 由於 `f2` 內沒有定義叫作 `g1` 的變數，因此第 11 行的 `g1` 指的是第 1 行的全域變數 `g1`。 第 11 行會將該全域變數設定為 10
        4. 第 12 行將區域變數 `c` 設定為 40。 但因為回傳前都沒有再用到了，所以沒有影響
        5. 回傳 `v`， 也就是回傳 70
    3. 回到第 19 行，此時全域變數 `g2` 為 70
4. 第 19 行 `printf` 印出 70

因此答案為 (A) 選項。

## 第 21 題

```c=
int F (int x, int y) {
    if (x < 1)
        return 1;
    else
        return F(x - y, y) + F(x - 2 * y, y);
}
```

若以 `F(5, 2)` 呼叫此函式，分析函式執行順序如下：

1. 第 2 行， 5 沒有小於 1， 因此跳過第 3 行
2. 第 4 行， 執行 `F(x - y, y) + F(x - 2 * y, y)`， 代入 `x = 5` 和 `y = 2`， 也就是執行 `F(3, 2) + F(1, 2)`
    1. 首先是 `F(3, 2)` 的部份
        1. 第 2 行， 3 沒有小於 1， 因此跳過第 3 行
        2. 第 4 行， 執行 `F(x - y, y) + F(x - 2 * y, y)`， 代入 `x = 3` 和 `y = 2`， 也就是執行 `F(1, 2) + F(-1, 2)`
            1. 首先是 `F(1, 2)` 的部份
                1. 第 2 行， 1 沒有小於 1， 因此跳過第 3 行
                2. 第 4 行， 執行 `F(x - y, y) + F(x - 2 * y, y)`， 代入 `x = 1` 和 `y = 2`， 也就是執行 `F(-1, 2) + F(-3, 2)`
                    1. 首先是 `F(-1, 2)` 的部份，由於第 2 行中 -1 小於 1， 因此回傳 1
                    2. 再來是 `F(-3, 2)` 的部份，由於第 2 行中 -3 小於 1， 因此回傳 1
                3. 第 4 行回傳 `1 + 1 = 2`
            2. 再來是 `F(-1, 2)` 的部份，由於第 2 行中 -1 小於 1， 因此回傳 1
        3. 第 4 行回傳 `2 + 1 = 3`
    2. 再來是 `F(1, 2)` 的部份，從上述步驟可得知， `F(1, 2)` 會回傳 2
3. 第 4 行回傳 `3 + 2 = 5`

最後的回傳值為 5， 答案為 \(C\) 選項。

## 第 22 題

1. `!(X1 || X2)` 為 `true`， 也就是 `X1 || X2` 為 `false`
2. `X1 || X2` 為 `false`， 只有在 `X1` 和 `X2` 皆為 `false` 的情況下才有可能成立

因此答案為 (A) 選項。

## 第 23 題

計算機組織基本概念題，答案為 (A) 選項。

## 第 24 題

程式設計（一）基本概念題，答案為 (A) 選項。

## 第 25 題

此題探討的是運算子的優先度 (precedence)， 優先度較高的運算子必須要先運算；如果優先度一樣，則由左至右計算。

在 C 語言中，乘除 (`*`, `/`, `%`) 的優先度高於加減 （`+`, `-`）。 因此， `a + b * c - e` 應該被解析為 `a + （b * c） - e`。 而加減的優先度一樣，因此由左至右計算，也就是左邊要先算，應解析為 `((a + （b * c）) - e)`。 因此答案為 \(C\) 選項。

## 討論區

如果有疑問，可以點選左上方的鉛筆符號或是雙頁符號，直接複製以下範例發問喔~

> 請問第 N 題的 XXX 為什麼會 OOO 呢？ [name=kinoe_T]
