<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`