110 高普考普通考試 資訊處理 程式設計概要 考古題詳解
第 一、 題25 分
PHP 是網際網路應用系統常用之程式語言。
(一)請寫出以下 PHP 程式的執行結果,並說明得到此結果的原因。(10 分)
<?php $a = array("a" => 1, "b" => 0); if($a["b"] == NULL) echo "null"; else echo "not null"; ?>(二)以下 PHP 程式(檔名 input.php)以瀏覽器初次執行會顯示如下畫面。在「Your name」欄位輸入資料後按 OK 鍵,會顯示輸入資料;若未輸入資料按 OK 鍵,則會再次顯示右下畫面。請完成程式(I)~(III)指令,使程式正確執行上述功能。(15 分)
🖼️【此處有附圖,請對照原卷】
<html> <head><title>Input Data</title></head> <?php if(is_null(____) || (____ === "")){ ?> <form method="____" action="input.php"> <p>Your name: <input type="text" name="name"></p> <input type="submit" value="OK"> </form> <?php } else { ?> <p>Thank you, <?php ____ $_GET['name'] ?></p> <?php } ?> </html>登入後即可作答並保存紀錄。
核心觀念
本題考查 PHP 的寬鬆比較、NULL 與空字串的判斷,以及以 GET 方法接收表單資料。
==是寬鬆比較,會依 PHP 的型別轉換規則比較值。===是嚴格比較,值與型別都必須相同。$_GET['name']用來讀取網址查詢參數中的name欄位。- 表單使用
method="GET"時,送出的欄位會放在$_GET中;echo可輸出資料。
解題方法
(一)陣列中的 `
第 二、 題25 分
程式語言 C 的程式碼是由許多函式(Function)組成。
#include <stdio.h>
int memo[20][20], number=0;
int B(int n, int k){ if((n >= 0)&&(k >= 0)&&(n >= k)) if((k == 0)||(k == n)){ memo[n][k] = 1; return 1; } else if(memo[n][k] > 0) return memo[n][k]; else{ memo[n][k] = B(n-1, k-1) + B(n-1, k); number += 2; return memo[n][k]; } else return 0; }
void f(int N, int M){ int sum=0; for(int i=1; i<=N; i++){ if(i>=10) break; if(i%3==0) continue; sum = sum + B(i, 2); } printf("%d %d ", sum, number); }
int g(int N, int M){ if((N<=0)||(M<0)) return 1; else return(M + N + g(M-2, N-3)); }
int main(){ f(20, 10); printf("%d\n", g(20, 10)); return 0; }
(一)請說明上述程式執行的結果。(15 分)
(二)請說明上述程式中 break 與 continue 指令的意義,並比較兩個指令之功能差異。(5 分)
(三)請說明 C 程式使用遞迴(Recursion)與迴圈(Loop),在時間、空間與程式可讀性之優缺點。(5 分)
登入後即可作答並保存紀錄。
核心觀念
本題主要考查 C 語言的流程控制、遞迴呼叫與全域變數:
B(n, k)遞迴計算二項係數,並以全域陣列memo記錄已計算的結果。- 全域變數
number只在遞迴式實際展開時增加;查表命中或遇到基底情況時不增加。 break會直接結束所在迴圈;continue會略過本次迴圈剩餘敘述,進入下一次迭代。g以遞迴方式改變參數,直到符合終止條件。
解題方法
(一)程式執行結果
1. 計算 f(20, 10)
f 中的迴圈從 i=1 開始,遇到 i>=10 就執行 break,因此只處理 到 。其中 為 3 的倍數時,continue 跳過該次迴圈,所以實際計算的 為:
每次計算 B(i, 2)。函式 B 計算二項係數 ;本題的結果依序為:
B(i, 2) | number 增加量 | |
|---|---|---|
| 1 | 0 | 0 |
| 2 | 1 | 0 |
| 4 | 6 | 2 |
| 5 | 10 | 2 |
| 7 | 21 | 2 |
| 8 | 28 | 2 |
說明:
B(1,2)因 ,不符合B的有效條件,回傳 0。B(2,2)是基底情況 ,回傳 1;基底情況不增加number。B(4,2)首次展開遞迴,計算後令number增加 2。B(5,2)、B(7,2)、B(8,2)各自展開一次;遞迴所需的子問題已由前面的計算寫入memo,因此子呼叫命中快取而不再展開。
因此:
f 印出 66 8 ,最後一個數字後有一個空格。
2. 計算 g(20, 10)
遞迴呼叫的參數變化如下:
| 呼叫 | 判斷/計算 |
|---|---|
g(20,10) | 回傳 |
g(8,17) | 回傳 |
g(15,5) | 回傳 |
g(3,12) | 回傳 |
第 三、 題25 分
Java 是常用的物件導向程式語言。
(一)請寫出以下三個 Java 程式的執行結果。(15 分)
(1)
class square { int edge; square(int e){ edge = e; } }
public class app { public static void main(String args[]) { square s1 = new square(10); square s2 = new square(10); if(s1 == s2) System.out.print("Equal square"); else System.out.print("Not equal square"); } }
(2)
public class app { public static void main(String args[]) { int a[] = {1,2,3,4,5}; show(a); }
public static void show(int i){
System.out.println(i);
}
public static void show(int b[]){
for(int i = 0; i < b.length; i++)
System.out.print(b[i] + " ");
}
}
(3)
class Circle { protected double radius;
Circle(double r){ radius = r; }
void show(){ System.out.print(radius); }
}
class Coin extends Circle { private int value;
Coin(double r, int v){
super(r);
value = v;
}
void show(){ System.out.print(radius+" "+value); }
}
public class app { public static void main(String args[]){ Circle coin = new Coin(3.0, 10); coin.show(); } }
(二)下列 Java 程式之要求為:設定變數 color 的值並輸出。請指出其編譯錯誤原因,並針對該錯誤原因說明程式如何修正使之能正確執行。(10 分)
class Car { private String color;
void showcolor() {
System.out.println(color);
}
}
public class app { public static void main(String args[]) { Car c1 = new Car(); c1.color = "blue"; c1.showcolor(); } }
登入後即可作答並保存紀錄。
(1)物件參考比較
核心觀念: == 用來比較兩個參考變數是否指向同一個物件。對類別物件而言,它不會自動比較物件欄位的內容。若要依欄位內容判斷相等,須另行定義比較方式,例如覆寫 equals。
解題方法: s1 與 s2 分別由兩次 new square(10) 建立,因此是兩個不同物件。兩者的 edge 欄位雖然都為 10,但參考位置不同,s1 == s2 為 false,執行 else 分支。
解題技巧: 看到物件之間使用 ==,先判斷是否為同一個物件;欄位值相同不代表物件參考相同。
執行結果:
Not equal square
(2)方法多載與陣列參數
核心觀念: Java 可用相同方法名稱搭配不同參數型別或參數數量來多載(overload)。int[] 是整數陣列型別,與單一整數 int 不同。
解題方法: 呼叫 show(a) 時,a 的型別是 int[],因此會選擇參數為 int[] 的 show 方法。該方法逐一輸出陣列元素,並在每個元素後輸出一個空格;程式沒有呼叫 println,所以輸出後不會自動換行。
解題技巧: 多載方法依引數型別及數量選擇;陣列引數不會被當成陣列中的單一元素型別。
執行結果:
1 2 3 4 5
(3)繼承、覆寫與動態繫結
核心觀念: 子類別可以覆寫父類別方法。透過父類別型別的參考呼叫被覆寫的方法時,Java 會依物件實際建立的型別決定執行哪個版本,這稱為動態繫結。
解題方法: coin 的宣告型別是 Circle,但它實際參考的是 new Coin(3.0, 10) 所建立的 Coin 物件。呼叫 coin.show 時,執行 Coin 覆寫的 show。建構子先以 super(r) 將半徑設為 3.0,再將 value 設為 10;覆寫的方法依序輸出半徑、空格和值。
第 四、 題25 分
程式語言 C 可使用不同資料型別的變數存取資料與傳遞函式的參數。
#include <stdio.h> #include <stdlib.h> #include <string.h>
void myFunction(int *a, int b, int *c, char *d){ c[1] = *a + b; d[*c] = d[2]; b = 17; int *r = c + 1; c = a; *c = *a + 1; printf("during:%s %d %d %d %d\n", &d[1], *a, b, *c, *r); }
int main(){ char animal[7] = "cat"; int x = strlen(animal); int z[3] = {1, 3, 5}; int *y = (int *)malloc(sizeof(int)*3); int *p = &x; int *q = &z[1];
q[1] = *p + 10;
printf("before:%s %d %d %d %d\n", animal, *z, z[1], z[2], x);
myFunction(p, x, q, animal);
printf("after:%s %d %d %d %d\n", animal, z[0], z[1], z[2], x);
return 0;
}
(一)請說明上述程式執行的結果。(15 分)
(二)請說明比較 C 程式宣告一個陣列時,如上述程式變數 y、z,使用一般陣列變數與指標變數的異同。(5 分)
(三)請說明比較 C 程式語言中,函式參數傳遞方法,傳值呼叫(call by value)與傳址呼叫(call by address)的異同。(5 分)
登入後即可作答並保存紀錄。
核心觀念
本題主要考查 C 語言的指標與陣列存取、函式參數傳遞,以及區域變數的作用範圍。
- 陣列名稱在多數運算式中會轉換為指向首元素的指標,因此
z[i]等同於*(z + i),q[i]等同於*(q + i)。 - C 函式的參數一律以傳值方式傳遞。傳入指標時,複製的是位址值;函式可以透過該位址修改呼叫端資料,但重新指定函式內的指標,不會改變呼叫端的指標。
- 函式內區域變數
b與main中同名以外的變數是不同變數;修改b不會直接修改main中的x。
解題方法
依序追蹤 main 初始資料、呼叫前的修改、函式執行中的每一個指標操作,再列出函式返回後的資料。
呼叫函式前
char animal[7] = "cat";
int x = strlen(animal);
int z[3] = {1, 3, 5};
int *p = &x;
int *q = &z[1];
animal 以空字元結尾,字串 "cat" 長度為 ,所以 x = 3。y 雖然配置了三個 int 的空間,但本題沒有使用它。
q 指向 z[1]。因此:
q[1] = *p + 10;
等同於 z[2] = x + 10,所以 z[2] = 13。此時:
animal = "cat"
x = 3
z = {1, 3, 13}
呼叫函式前的輸出為:
before:cat 1 3 13 3
myFunction 執行期間
呼叫時,a 指向 x,b 複製 x 的值 ,c 指向 z[1],d 指向 animal[0]。
-
c[1] = *a + b;c[1]是z[2],而*a是x = 3、b = 3,所以z[2] = 6。 -
d[*c] = d[2];此時*c是z[1] = 3,所以此式等同於animal[3] = animal[2]。animal[2]是't',因此animal的字元陣列變成{'c','a','t','t',...}。原本的空字元仍在animal[3]嗎?這個位置已被改為't',所以原字串結尾被覆寫;而animal[4]原本為'\0',新的字串內容為"catt"。 -
b = 17;只改變函式內的區域變數b,不會改變x。 -
int *r = c + 1;r指向z[2]。 -
c = a;只改變函式內的指標c,使它指向x;原本的q仍指向z[1]。 -
*c = *a + 1;c與a都指向x,因此將x改為 。