普考申論題
112年
[資訊處理] 程式設計概要
第 二 題
📖 題組:
一、根據以下C程式碼,回答下列問題:
1 #include <stdio.h>
2 void g(int *x, int *y) {
3 *x = *y - 1;
4 *y = *y - 2;
5 printf("*x = %d, *y = %d\n", *x, *y);
6 }
7
8 void f(int *z, int *w) {
9 int n = 13;
10 g(w, &n);
11 printf("*z = %d, *w = %d, n = %d\n", *z, *w, n);
12 }
13
14 int main() {
15 int i = 21;
16 int j = 5;
17 int n = 137;
18 f(&i, &j);
19 printf("print 1: i = %d, j = %d, n = %d\n", i, j, n);
20 g(&n, &n);
21 printf("print 2: i = %d, j = %d, n = %d\n", i, j, n);
22 return 0;
23 }
一、根據以下C程式碼,回答下列問題:
1 #include <stdio.h>
2 void g(int *x, int *y) {
3 *x = *y - 1;
4 *y = *y - 2;
5 printf("*x = %d, *y = %d\n", *x, *y);
6 }
7
8 void f(int *z, int *w) {
9 int n = 13;
10 g(w, &n);
11 printf("*z = %d, *w = %d, n = %d\n", *z, *w, n);
12 }
13
14 int main() {
15 int i = 21;
16 int j = 5;
17 int n = 137;
18 f(&i, &j);
19 printf("print 1: i = %d, j = %d, n = %d\n", i, j, n);
20 g(&n, &n);
21 printf("print 2: i = %d, j = %d, n = %d\n", i, j, n);
22 return 0;
23 }
📝 此題為申論題,共 2 小題
小題 (二)
請問該程式碼執行後輸出的結果為何?(15分)
思路引導 VIP
看到本題,需要動手追蹤各變數的狀態與記憶體位址的綁定。特別注意三點:1. main 的 n 與 f 的 n 是不同作用域的變數。2. f 傳入 &i 和 &j,對其取值修改會連帶影響 main 的原始變數。3. main 第20行呼叫 g(&n, &n) 時,傳入兩個相同的位址,這是典型的「別名效應(Aliasing)」,修改 *x 即等同修改 *y,必須非常小心運算順序。
小題 (一)
請說明程式碼第8行至第12行中,每一行之運算子符號「*」及「&」操作所代表的意義。(10分)
思路引導 VIP
看到本題,首先要辨識出這是C語言的指標操作。接著應該分別指出在「宣告變數型別」與「執行運算子」時,符號的不同意義:宣告時的「」是定義指標變數,運算時的「&」是取址運算(Address-of),運算時的「」是提領/取值運算(Dereference)。要逐行詳細說明這兩個符號的作用目標。
C語言指標與作用域
💡 掌握傳址呼叫、變數作用域及指標別名效應之程式追蹤。
🔗 程式追蹤與狀態變化流程
- 1 環境初始化 — 區分 main 與 f 的局部變數,標註其獨立記憶體位址。
- 2 傳址呼叫對應 — 確認函式參數指標 z, w, x, y 具體指向哪個變數。
- 3 逐行賦值追蹤 — 依序計算表達式並更新指標指向的原始變數數值。
- 4 別名同步更新 — 當 &n 同時傳入 x, y 時,確保 x 修改後 y 也同步變動。
↓
↓
↓
🔄 延伸學習:延伸學習:探討指標參數加上 const 修飾符對於傳址修改的限制。