<style> .markdown-body table{ display: unset; } </style> # APCS觀念題2017年3月 > 日期:2023年2月6日 > 作者:王一哲 1. 給定一個 1x8 的陣列 A,A = {0, 2, 4, 6, 8, 10, 12, 14}。下列函式 Search(x) 真正目的是找到 A 之中大於 x 的最小值。然而,這個函式有誤。請問下列哪個函式呼叫可測出函式有誤? (A) Search(-1)   (B) Search(0)   \(C\) Search(10)   (D) Search(16) ```c int A[8]={0, 2, 4, 6, 8, 10, 12, 14}; int Search (int x) { int high = 7; int low = 0; while (high > low) { int mid = (high + low)/2; if (A[mid] <= x) { low = mid + 1; } else { high = mid; } } return A[high]; } ``` <br /> <span style="font-weight:bold">答案</span>:D <span style="color:blue">詳解</span>:呼叫 Search(16) 時,其中的 while 迴圈運作流程如下: 1. 第1次:原來的值 high = 7、low = 0,得到 mid = 3,由於 A[3] = 6 <= 16,得到 low = 4。 2. 第2次:原來的值 high = 7、low = 4,得到 mid = 5,由於 A[5] = 10 <= 16,得到 low = 6。 3. 第3次:原來的值 high = 7、low = 6,得到 mid = 6,由於 A[6] = 12 <= 16,得到 low = 7。由於 high == low,跳出迴圈。 回傳值為 14,但這 14 < 16,不是 A 之中大於 x 的最小值,程式有誤。 <br /><br /> 2. 給定函式 A1()、 A2() 與 F() 如下,以下敘述何者**有誤**? (A) A1(5) 印的 \* 個數比 A2(5) 多     (B) A1(13) 印的 \* 個數比 A2(13) 多 \(C\) A2(14) 印的 \* 個數比 A1(14) 多   (D) A2(15) 印的 \* 個數比 A1(15) 多 ```c void A1 (int n) { F(n/5); F(4*n/5); } void A2 (int n) { F(2*n/5); F(3*n/5); } void F (int x) { int i; for (i=0; i<x; i=i+1) printf("*"); if (x>1) { F(x/2); F(x/2); } } ``` <br /> <span style="font-weight:bold">答案</span>:D <span style="color:blue">詳解</span>:列出計算過程,輸出的 \* 數量以數字表示。A選項正確 $$ \begin{align*} A1(5) &= F(1) + F(4)\\ &= 1 + [4 + 2 \times F(2)]\\ &= 1 + \{4 + 2 \times [2 + 2 \times F(1)]\}\\ &= 1 + 12\\ &= 13\\ A2(5) &= F(2) + F(3)\\ &= [2 + 2 \times F(1)] + [3 + 2 \times F(1)]\\ &= 4 + 5\\ &= 9 \end{align*} $$ B選項正確 $$ \begin{align*} A1(13) &= F(2) + F(10)\\ &= 4 + [10 + 2 \times F(5)]\\ &= 4 + \{10 + 2 \times [5 + 2 \times F(2)]\}\\ &= 4 + [10 + 2 \times (5 + 2 \times 4)]\\ &= 4 + 36\\ &= 40\\ A2(13) &= F(5) + F(7)\\ &= [5 + 2 \times F(2)] + [7 + 2 \times F(3)]\\ &= 13 + 17\\ &= 30 \end{align*} $$ C選項正確 $$ \begin{align*} A1(14) &= F(2) + F(11)\\ &= 4 + [11 + 2 \times F(5)]\\ &= 4 + (11 + 2 \times 13)\\ &= 4 + 37\\ &= 41\\ A2(14) &= F(5) + F(8)\\ &= [5 + 2 \times F(2)] + [8 + 2 \times F(4)]\\ &= 13 + (8 + 2 \times 12)\\ &= 45 \end{align*} $$ D選項錯誤 $$ \begin{align*} A1(15) &= F(3) + F(12)\\ &= [3 + 2 \times F(1)] + [12 + 2 \times F(6)]\\ &= 5 + \{12 + 2 \times [6 + 2 \times F(3)] \}\\ &= 5 + [12 + 2 \times (6 + 2 \times 5)]\\ &= 5 + 44\\ &= 49\\ A2(15) &= F(6) + F(9)\\ &= [6 + 2 \times F(3)] + [9 + 2 \times F(4)]\\ &= (6 + 2 \times 5) + (9 + 2 \times 12)\\ &= 16 + 33\\ &= 49 \end{align*} $$ <br /><br /> 3. 下列 F()函式回傳運算式該如何寫,才會使得 F(14) 的回傳值為40? (A) n \* F(n-1)   (B) n + F(n-3)   \(C\) n - F(n-2)   (D) F(3\*n+1) ```c int F (int n) { if (n < 4) return n; else return _______?_______; } ``` <br /> <span style="font-weight:bold">答案</span>: <span style="color:blue">詳解</span>:列出運作過程,A選項錯誤 $$ \begin{align*} F(14) &= 14 \times F(13)\\ &= 14 \times 13 \times F(12)\\ &= 14 \times 13 \times 12 \times \dots \times 3\\ &= 43589145600 \end{align*} $$ 題目中回傳值格式設定為 int,會溢位,顯示為 639472640,若要顯示正確的數值,回傳值格式要設定成 long 或 unsigned long。如果只是要解題,在列出兩行算式後,即可看出回傳值遠大於40,A選項錯誤。 B選項正確 $$ \begin{align*} F(14) &= 14 + F(11)\\ &= 14 + 11 + F(8)\\ &= 14 + 11 + 8 + F(5)\\ &= 14 + 11 + 8 + 5 + F(2)\\ &= 14 + 11 + 8 + 5 + 2\\ &= 40 \end{align*} $$ C選項錯誤 $$ \begin{align*} F(14) &= 14 - F(12)\\ &= 14 - [12 - F(10)]\\ &= 14 - 12 + [10 - F(8)]\\ &= 14 - 12 + 10 - [8 - F(6)]\\ &= 14 - 12 + 10 - 8 + [6 - F(4)]\\ &= 14 - 12 + 10 - 8 + 6 - [4 - F(2)]\\ &= 14 - 12 + 10 - 8 + 6 - 4 + 2\\ &= 8 \end{align*} $$ D選項不會收歛,錯誤。 $$ F(14) = F(43) = F(130) = \dots $$ <br /><br /> 4. 右側函式兩個回傳式分別該如何撰寫,才能正確計算並回傳兩參數 a, b 之最大公因數 (Greatest Common Divisor)? (A) a, GCD(b,r)   (B) b, GCD(b,r)   \(C\) a, GCD(a,r)   (D) b, GCD(a,r) ```c int GCD (int a, int b) { int r; r = a % b; if (r == 0) return __________; return _____________; } ``` <br /> <span style="font-weight:bold">答案</span>:B <span style="color:blue">詳解</span>:本題考函式的遞迴 (recursion)。當餘數r等於0時,除數b即為最大公因數,因此第一個回傳值為b;當餘數r不等於0時,要將這次運算時的除數b當作下次運算時的被除數,將這次運算時的餘數r當作下次運算時的除數,因此第一個回傳值為 GCD(b,r);答案為B。 <br /><br /> 5. 若 A 是一個可儲存 n 筆整數的陣列,且資料儲存於 A[0] ~ A[n-1]。 經過下列程式碼運算後,以下何者敘述不一定正確? (A) p 是 A 陣列資料中的最大值   (B) q 是 A 陣列資料中的最小值    \(C\) q < p             (D) A[0] <= p ```c int A[n]={ … }; int p = q = A[0]; for (int i=1; i<n; i=i+1) { if (A[i] > p) p = A[i]; if (A[i] < q) q = A[i]; } ``` <br /> <span style="font-weight:bold">答案</span>:C <span style="color:blue">詳解</span>:如果陣列A的每個元素皆相同,程式碼運算後 p == q,C選項不一定正確。 <br /><br /> 6. 若 A[][] 是一個 MxN 的整數陣列,下列程式片段用以計算 A 陣列每一列的總和,以下敘述何者正確? (A) 第一列總和是正確,但其他列總和不一定正確 (B) 程式片段在執行時會產生錯誤 (run-time error) \(C\) 程式片段中有語法上的錯誤 (D) 程式片段會完成執行並正確印出每一列的總和 ```c void main () { int rowsum = 0; for (int i=0; i<M; i=i+1) { for (int j=0; j<N; j=j+1) { rowsum = rowsum + A[i][j]; } printf("The sum of row %d is %d.\n", i, rowsum); } } ``` <br /> <span style="font-weight:bold">答案</span>:A <span style="color:blue">詳解</span>:A選項正確,由於外層的 for 迴圈運作完一次之後,沒有將變數 rowsum 重設為0,會繼續累加上去,應該修正為 ```c void main () { int rowsum = 0; for (int i=0; i<M; i=i+1) { rowsum = 0; for (int j=0; j<N; j=j+1) { rowsum = rowsum + A[i][j]; } printf("The sum of row %d is %d.\n", i, rowsum); } } ``` <br /><br /> 7. 若以 B(5,2)呼叫下列 B()函式,總共會印出幾次 “base case”? (A) 1   (B) 5   \(C\) 10   (D) 19 ```c int B (int n, int k) { if (k == 0 || k == n){ printf ("base case\n"); return 1; } return B(n-1,k-1) + B(n-1,k); } ``` <br /> <span style="font-weight:bold">答案</span>:C <span style="color:blue">詳解</span>:當 k == 0 或 k == n 時,也就是函式B的第二個參數為0或兩個參數相等時,印出一次 "base case"。B(5, 2) 運作過程如下: $$ \begin{align*} B(5, 2) &= B(4, 1) + B(4, 2)\\ &= [B(3, 0) + B(3, 1)] + [B(3, 1) + B(3, 2)]\\ &= 1 + 2 \times [B(2, 0) + B(2, 1)] + [B(2, 1) + B(2, 2)]\\ &= 1 + 2 + 3 \times B(2, 1) + 1\\ &= 4 + 3 \times [B(1, 0) + B(1, 1)]\\ &= 4 + 3 \times (1 + 1)\\ &= 10 \end{align*} $$ <br /><br /> 8. 給定下列程式,其中 s 有被宣告為全域變數,請問程式執行後輸出為何? (A) 1,6,7,7,8,8,9   (B) 1,6,7,7,8,1,9   \(C\) 1,6,7,8,9,9,9   (D) 1,6,7,7,8,9,9 ```c int s = 1; // 全域變數 void add (int a) { int s = 6; for( ; a>=0; a=a-1) { printf("%d,", s); s++; printf("%d,", s); } } int main () { printf("%d,", s); add(s); printf("%d,", s); s = 9; printf("%d", s); return 0; } ``` <br /> <span style="font-weight:bold">答案</span>:B <span style="color:blue">詳解</span>:程式運作流程如下: 1. 於主程式中,由於全域變數s初始值為1,第1個 printf 會印出1。 2. 呼叫函式 add(s),輸入的參數值為1。 3. 進到函式 add 中,區域變數s值初始值為6,由於輸入的參數值為1,for 迴圈會運作2次。第1次運作時,第1個 printf 會印出6,再將s值重設為7,第2個 printf 會印出7。第2次運作時,第1個 printf 會印出7,再將s值重設為8,第2個 printf 會印出8。離開函式add。 4. 回到主程式。由於**函式 add 中的區域變數s值不會傳到外面,主程式中的s值仍為1**,第2個 printf 會印出1。將s值重設為9,第3個 printf 會印出9。 在 Python 裡也有同樣的觀念,以下的程式碼輸出值也是 1, 6, 7, 7, 8, 1, 9,如果要讓自訂函式 add 裡的變數s值傳到函式外面,需要刪除第4行的註解符號,這樣輸出值就會變成 1, 6, 7, 7, 8, 8, 9。 ```python= s = 1 def add(a): #global s s = 6 while a >= 0: print("{:d}, ".format(s), end="") s += 1 print("{:d}, ".format(s), end="") a -= 1 print("{:d}, ".format(s), end="") add(s) print("{:d}, ".format(s), end="") s = 9 print("{:d}".format(s)) ``` <br /><br /> 9. 下列 F()函式執行時,若輸入依序為整數 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,請問 X[] 陣列的元素值依順序為何? (A) 0, 1, 2, 3, 4, 5, 6, 7, 8, 9   (B) 2, 0, 2, 0, 2, 0, 2, 0, 2, 0    \(C\) 9, 0, 1, 2, 3, 4, 5, 6, 7, 8   (D) 8, 9, 0, 1, 2, 3, 4, 5, 6, 7 ```c void F () { int X[10] = {0}; for (int i=0; i<10; i=i+1) { scanf("%d", &X[(i+2)%10]); } } ``` <br /> <span style="font-weight:bold">答案</span>:D <span style="color:blue">詳解</span>:由 (i+2)%10 可知填入陣列X的引值依序為2, 3, 4, 5, 6, 7, 8, 9, 0, 1,因此陣列X的元素值依序為8, 9, 0, 1, 2, 3, 4, 5, 6, 7。 <br /><br /> 10. 若以 G(100) 呼叫下列函式後,n的值為何? (A) 25   (B) 75   \(C\) 150   (D) 250 ```c int n = 0; void K (int b) { n = n + 1; if (b % 4) K(b+1); } void G (int m) { for (int i=0; i<m; i=i+1) { K(i); } } ``` <br /> <span style="font-weight:bold">答案</span>:D <span style="color:blue">詳解</span>:函式 G 會依序執行 K(0)、K(1)、K(2)、…、K(99)。接下來觀察函式 K 的執行規律,若呼叫 K(0),執行 n = n + 1,因為 0 % 4 == 0,結束函式。 若呼叫 K(1) 1. 執行 n = n + 1,因為 1 % 4 == 1,呼叫 K(2)。 2. 執行 n = n + 1,因為 2 % 4 == 2,呼叫 K(3)。 3. 執行 n = n + 1,因為 3 % 4 == 3,呼叫 K(4)。 4. 執行 n = n + 1,因為 4 % 4 == 0,結束函式。 若呼叫 K(2) 1. 執行 n = n + 1,因為 2 % 4 == 2,呼叫 K(3)。 2. 執行 n = n + 1,因為 3 % 4 == 3,呼叫 K(4)。 3. 執行 n = n + 1,因為 4 % 4 == 0,結束函式。 若呼叫 K(3) 1. 執行 n = n + 1,因為 3 % 4 == 3,呼叫 K(4)。 2. 執行 n = n + 1,因為 4 % 4 == 0,結束函式。 K(5) 的運作流程與 K(0) 相同,因此可以將 K(0)、K(1)、K(2)、…、K(99) 分為25組,每組會執行 n = n + 1 共10次,所以 G(100) 會執行 n = n + 1 共250次,最後 n 的值為250,答案為D。 <br /><br /> 11. 若 A[1]、A[2] 和 A[3]分別為陣列 A[]的三個元素(element),下列那個程式片段可以將 A[1] 和 A[2] 的內容交換? (A) A[1] = A[2]; A[2] = A[1];        (B) A[3] = A[1]; A[1] = A[2]; A[2] = A[3];    \(C\) A[2] = A[1]; A[3] = A[2]; A[1] = A[3];   (D) 以上皆可 <br /> <span style="font-weight:bold">答案</span>:B <span style="color:blue">詳解</span>:B選項,先將 A[1] 的值指定給 A[3],再把 A[2] 的值指定給 A[1],最後把 A[3] 的值,也就是 A[1] 原來的值指定給 A[2],就能把 A[1] 和 A[2] 的值交換。 <br /><br /> 12. 若函式 rand()的回傳值為一介於 0 和 10000 之間的亂數,下列那個運算式可產生介於 100 和 1000 之間的任意數(包含 100 和 1000)? (A) rand() % 900 + 100   (B) rand() % 1000 + 1    \(C\) rand() % 899 + 101   (D) rand() % 901 + 100 <br /> <span style="font-weight:bold">答案</span>:D <span style="color:blue">詳解</span>:rand() % 901 輸出值範圍為 0 ~ 900,再加 100 則範圍變成 100 ~ 1000,答案為D。 <br /><br /> 13. 下列程式片段無法正確列印 20 次的"Hi!", ```c for (int i=0; i<=100; i=i+5) { printf ("%s\n", "Hi!"); } ``` 請問下列哪一個修正方式仍無法正確列印 20 次的"Hi!"? (A) 需要將 i<=100 和 i=i+5 分別修正為 i<20 和 i=i+1 (B) 需要將 i=0 修正為 i=5 \(C\) 需要將 i<=100 修正為 i<100; (D) 需要將 i=0 和 i<=100 分別修正為 i=5 和 i<100 <br /> <span style="font-weight:bold">答案</span>:D <span style="color:blue">詳解</span>:D選項的修正方式,for 迴圈執行時 i 的值依序為 5、10、15、…、95,共執行19次。 <br /><br /> 14. 若以 F(15)呼叫下列 F() 函式,總共會印出幾行數字? (A) 16 行   (B) 22 行   \(C\) 11 行   (D) 15 行 ```c void F (int n) { printf ("%d\n" , n); if ((n%2 == 1) && (n > 1)){ return F(5*n+1); } else { if (n%2 == 0) return F(n/2); } } ``` <br /> <span style="font-weight:bold">答案</span>:D <span style="color:blue">詳解</span>:本題考函式的遞迴 (recursion),遞迴出口於 if ((n%2 == 1) && (n > 1)),當n的值為2的整數倍次方時才會結束遞迴。每呼叫函式 F 一次,就會印出當時n的值,代入的n值依序為:15、76、38、19、96、48、24、12、6、3、16、8、4、2、1,共15個。 <br /><br /> 15. 給定下列函式 F(),執行 F() 時哪一行程式碼可能永遠不會被執行到? (A) a = a + 5;   (B) a = a + 2;   \(C\) a = 5;   (D) 每一行都執行得到 ```c void F (int a) { while (a < 10) a = a + 5; if (a < 12) a = a + 2; if (a <= 11) a = 5; } ``` <br /> <span style="font-weight:bold">答案</span>:C <span style="color:blue">詳解</span>:若呼叫 F(6),a的值在 while 迴圈中被重設為11,在第一個 if 中被重設為13,不符合第二個 if 的條件,a = 5 這行程式碼不會被執行,答案為C。 <br /><br /> 16. 給定右側函式 F(),已知 F(7) 回傳值為17,且 F(8) 回傳值為 25,請問 if 的條件判斷式應為何? (A) a % 2 != 1   (B) a * 2 > 16   \(C\) a + 3 < 12   (D) a * a < 50 ```c int F (int a) { if ( _____?_____ ) return a * 2 + 3; else return a * 3 + 1; } ``` <br /> <span style="font-weight:bold">答案</span>:D <span style="color:blue">詳解</span>:F(7) 必須符合條件才會回傳17,F(8) 必須不符合條件才會回傳25,只有D選項符合要求。 <br /><br /> 17. 給定下列函式 F(), F() 執行完所回傳的 x 值為何? (A) $n(n+1) \sqrt{\log_2 n}$     (B) $n^2 (n+1)/2$    \(C\) $n(n+1)[\log_2 n + 1]/2$   (D) $n(n+1)/2$ ```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; } ``` <br /> <span style="font-weight:bold">答案</span>:C <span style="color:blue">詳解</span>:先看最內層的 for 迴圈,每次執行後會將k值乘以2,繼續執行迴圈的條件為 $$ y = 2^k \leq n ~\Rightarrow \log_2 y = k \log_2 2 \leq \log_2 n ~\Rightarrow~ k \leq \log_2 n $$ 總共執行 $\log_2 n + 1$次。接下來看外面兩層 for 迴圈的效果,若i為1,第二層 for 迴圈會執行 $n$ 次;若i為2,第二層 for 迴圈會執行 $n-1$ 次;若i為3,第二層 for 迴圈會執行 $n-2$ 次;若i為 $n$,第二層 for 迴圈會執行1次;執行次數共為 $$ n + (n-1) + (n-2) + \dots + 1 = \frac{n(n+1)}{2} $$ x = x + 1 被執行的次數等於最後輸出的值 $$ \frac{n(n+1)}{2} \cdot (\log_2 n + 1) $$ 答案為C。 <br /><br /> 18. 下列程式執行完畢後所輸出值為何? (A) 12   (B) 24   \(C\) 16   (D) 20 ```c int main() { int x = 0, n = 5; for (int i=1; i<=n; i=i+1) for (int j=1; j<=n; j=j+1) { if ((i+j)==2) x = x + 2; if ((i+j)==3) x = x + 3; if ((i+j)==4) x = x + 4; } printf ("%d\n", x); return 0; } ``` <br /> <span style="font-weight:bold">答案</span>:D <span style="color:blue">詳解</span>:i、j可能的值皆為1、2、3、4、5,只要找出 i+j 為 2、3、4 的組合,將這些值全部相加即為答案,共有下列6組,相加為20。 <div style="text-align:center"> <table> | i | j | i + j | |---|---|-----| | 1 | 1 | 2 | | 1 | 2 | 3 | | 1 | 3 | 4 | | 2 | 1 | 3 | | 2 | 2 | 4 | | 3 | 1 | 4 | </table> </div> <br /><br /> 19. 下列程式擬找出陣列 A[] 中的最大值和最小值。不過,這段程式碼有誤,請問 A[] 初始值如何設定就可以測出程式有誤? (A) {90, 80, 100}   (B) {80, 90, 100}   \(C\) {100, 90, 80}   (D) {90, 100, 80} ```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; } ``` <br /> <span style="font-weight:bold">答案</span>:B <span style="color:blue">詳解</span>:將選項B代件程式碼中,由於陣列 A[] 的值越大越大,程式運作時只會執行 if 中的程式碼,最後 M 的值為 100,但是不會執行 else if 中的程式碼,最後 N 的值仍為初始值 101,程式有誤。 <br /><br /> 20. 小藍寫了一段複雜的程式碼想考考你是否了解函式的執行流程。請回答程式最後輸出的數值為何? (A) 70   (B) 80   \(C\) 100   (D) 190 ```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; } ``` <br /> <span style="font-weight:bold">答案</span>:A <span style="color:blue">詳解</span>:可以使用以下的程式碼及輸出值觀察程式運作流程。 ```c= #include <stdio.h> int g1 = 30, g2 = 20; int f1(int v) { int g1 = 10; printf("f1(v), v = %d, g1 = %d, g1+v = %d\n", v, g1, g1+v); return g1+v; } int f2(int v) { int c = g2; printf("f2(v) input, v = %d, c = %d, g1 = %d\n", v, c, g1); v = v+c+g1; printf("f2(v) output, v = %d\n", v); g1 = 10; c = 40; return v; } int main(int argc, char* argv[]) { g2 = 0; g2 = f1(g2); printf("main: g1 = %d\n", g1); printf("f2(f2(g2)): %d\n", f2(f2(g2))); return 0; } ``` 輸出為 ```c= f1(v), v = 0, g1 = 10, g1+v = 10 main: g1 = 30 f2(v) input, v = 10, c = 10, g1 = 30 f2(v) output, v = 50 f2(v) input, v = 50, c = 10, g1 = 10 f2(v) output, v = 70 f2(f2(g2)): 70 ``` 1. 在 main 當中呼叫 f1(g2) 時,輸入的參數為0,由於在函式 f1 當中定義了區域變數 int g1 = 10,因此回傳值 g1 + v = 10 + 0 = 10,將變數 g2 重設為 10。**特別注意:區域變數 g1 的值不會傳到外面。** 2. 在 main 當中呼叫 f2(f2(g2)) 時,先處理裡面的 f2(g2),此時輸入的參數為 10,變數 c 設定為剛才被重設過的 g2 = 10,g1 則是採用全域變數的初始值 30,因此回傳值 v = v + c + g1 = 10 + 10 + 30 = 50。除了回傳值之外,**還會將全域變數 g1 重設為10**。 3. 處理 f2(f2(g2)) = f2(50),此時輸入的參數為 50,變數 c 設定為 10,g1 則是採用重設過的全域變數值 10,因此回傳值 v = v + c + g1 = 50 + 10 + 10 = 70,答案為A。 實務上會建議,**不要在自訂函式中的區域變數中使用與全域變數相同的名稱**,這會使程式碼讀起來很混亂。 <br /><br /> 21. 若以 F(5,2) 呼叫下列 F() 函式,執行完畢後回傳值為何? (A) 1   (B) 3   \(C\) 5   (D) 8 ```c int F (int x,int y) { if (x<1) return 1; else return F(x-y,y)+F(x-2*y,y); } ``` <br /> <span style="font-weight:bold">答案</span>:C <span style="color:blue">詳解</span>:運作流程如下 $$ \begin{align*} F(5, 2) &= F(3, 2) + F(1, 2)\\ &= [F(1, 2) + F(-1, 2)] + [F(-1, 2) + F(-3, 2)]\\ &= [F(-1, 2) + F(-3, 2)] + 1 + 1 + 1\\ &= 1 + 1 + 3\\ &= 5 \end{align*} $$ <br /><br /> 22. 若要邏輯判斷式 !(X<sub>1</sub> || X<sub>2</sub>)計算結果為真(True),則 X<sub>1</sub> 與 X<sub>2</sub> 的值分別應為何? (A) X<sub>1</sub> 為 False,X<sub>2</sub> 為 False   (B) X<sub>1</sub> 為 True,X<sub>2</sub> 為 True \(C\) X<sub>1</sub> 為 True,X<sub>2</sub> 為 False    (D) X<sub>1</sub> 為 False,X<sub>2</sub> 為 True <br /> <span style="font-weight:bold">答案</span>:A <span style="color:blue">詳解</span>:A選項 $$ \mathrm{!(False || False) = !False = True} $$ B選項 $$ \mathrm{!(True || True) = !True = False} $$ 選項 $$ \mathrm{!(True || False) = !True = False} $$ 選項 $$ \mathrm{!(False || True) = !True = False} $$ <br /><br /> 23. 程式執行時,程式中的變數值是存放在何處? (A) 記憶體   (B) 硬碟   \(C\) 輸出入裝置   (D) 匯流排 <br /> <span style="font-weight:bold">答案</span>:A <span style="color:blue">詳解</span>:程式執行時,資料會先放在記憶體中。 <br /><br /> 24. 程式執行過程中,若變數發生溢位情形,其主要原因為何? (A) 以有限數目的位元儲存變數值   (B) 電壓不穩定   \(C\) 作業系統與程式不甚相容   (D) 變數過多導致編譯器無法完全處理 <br /> <span style="font-weight:bold">答案</span>:A <span style="color:blue">詳解</span>:儲存變數值使用的位元數與資料型別以及編譯器有關,通常字元 char 使用8位元,整數 int 使用16或32位元,因此有儲存範圍限制,如果變數值超出範圍就會溢位。 <br /><br /> 25. 若 a, b, c, d, e 均為整數變數,下列哪個算式計算結果與 a+b\*c-e 計算結果相同? (A) (((a+b)\*c)-e)   (B) ((a+b)\*(c-e))   \(C\) ((a+(b\*c))-e)   (D) (a+((b\*c)-e)) <br /> <span style="font-weight:bold">答案</span>:C <span style="color:blue">詳解</span>:計算的原則如下 1. 先處理括號內的算式 2. 先乘除、後加減 3. 由左至右 A選項 (((a+b)\*c)-e) = a\*c + b\*c - e;B選項 ((a+b)\*(c-e)) = a\*c - a\*e + b\*c - b\*e;C選項 ((a+(b\*c))-e) = a + b\*c - e;D選項 (a+((b\*c)-e)) = a + (b\*c - e),會先計算後面的括號,再計算a加括號中的計算結果。如果連計算順序也考慮進去,則答案為C。 <br /><br /> --- ###### tags:`APCS`、`C`、`C++`、`Python`