通識計算機程式設計期中考參考解答, 4/23/2010 1. (a) 宣告 double 變數 z, bool 變數 b, int 變數 i (3%) 答 : double z; bool b; (b) 在螢幕顯示一行字, 要求使用者輸入一個浮點數. (3%) 答 : Console.WriteLine(" 輸入一個浮點數 "); (c) 自鍵盤讀入一個浮點數., 並將其值存入已宣告之 double 變數 z (3%) 答 : z = double.parse(console.readline()); (d) 令已宣告之 bool 變數 b 等於邏輯敘述 z > 0 的結果. (3%) 答 : b = z > 0; (e) 若.b 為真, 在螢幕顯示 z > 0 否則印出 z <= 0 (3%) 答 : if (b) Console.WriteLine("z > 0"); else Console.WriteLine("z <= 0"); 或 string message = b? "z > 0" : "z <= 0"; Console.WriteLine(message); 2. (a) 將已宣告設值之 int 變數 n 先設定 (assign) 給他處已宣告之 int 變數 m 後, 再使用遞增算子 ++ 加 1 (3%) 答 : m = n++; 或 m = n; ++n; 1/14
(b) 令他處已宣告之 int 變數 q 等於他處已宣告設值之 int 變數 p 除以 9 的商 (3%) 答 : q = p / 9; (c) 宣告 double 變數 db, 並令其值為 double 變數 x 之以 10 為底的對數值乘以 20.0 (3%) 答 : double db = 20.0 Math.Log10(x); (d) 宣告 string 變數 s, 利用三元運算子使其在他處已宣告設值之 double 變數 speed 大於等於 110.0 時等於 超速, 反之則等於 正常速率 (3%) 答 : string s = (speed >= 110.0)? " 超速 " : " 正常速率 "; (e) 宣告變數 r 為 char 型別, 並令其值為結束本行, 另起一行之 new line 字元 (3%) 答 : char r = '\n'; 3. 撰寫一或數個 C# 敘述達成下列要求 : ( 假設 using System; 敘述已經包含於程式中 ) (a) 宣告一個其值為 5 的 int 常數 ARRAY_SIZE (3%) 答 : const int ARRAY_SIZE = 5; (b) 宣告一個長度為 int 常數 ARRAY_SIZE 的 int 陣列, 命名為 a (3%) 答 : int[] a = new int[array_size]; (c) 寫一個 for 迴圈, 將陣列 a 的每個元素都設值為 0 (3%) 答 : for (i = 0; i < ARRAY_SIZE; ++i) a[i] = 0; (d) 將順序為第 3 的 a 陣列元素之值設為 9 (3%) 答 : a[2] = 9; (e) 將陣列 a 的所有元素之值印在同一行, 各元素值之間以水平定位符號 (tab) 分隔 ; 印完後螢幕畫面要結束本行, 另起一行 寫出螢幕輸出 (3%) 2/14
答 : for (i = 0; i < ARRAY_SIZE; ++i) Console.Write(a[i] + "\t"); Console.WriteLine(); 螢目輸出為 : 4.. (a) (3%) float d = 10.5; 答 :10.5 為 double 常數, 設為 float 變數時會損失精確度 更正 : double d = 10.5; 或 float d = 10.5f; 或 float d = (float) 10.5; (b) (3%) enum Color RED = 1, YELLOW = 2, GREEN = 3... Color color; Console.Write(" 輸入 1~3 的整數, 分別代表紅 黃 綠 "); int c = Convert.ToInt16(Console.ReadLine()); switch (c) case 1: color = RED; break; 3/14
case 2: color = YELLOW; break; case 3: color = GREEN; break; default: color = RED; break; 答 : 列舉型別之值使用時必須加上型別名稱更正 : Color color; Console.Write(" 輸入 1~3 的整數, 分別代表紅 黃 綠 "); int c = Convert.ToInt16(Console.ReadLine()); switch (c) case 1: color = Color.RED; break; case 2: color = Color.YELLOW; break; case 3: color = Color.GREEN; break; default: color = Color.RED; break; (c) (3%) 以下程式片段應計算 2 到 10 的偶數和. int sum = 0; for ( i=2; i < 10; i=i+2 ) sum += i; 答 : 此為 off by one error, 沒有把 10 加入 sum 之中更正 : int sum = 0; for (i = 2; i <= 10; i = i + 2) sum += i; (d) (3%) 以下程式片段應印出 計程很操! 字樣 3 次. int n = 1; do Console.WriteLine( 計程很操! ); 4/14
while ( n <= 3 ); 答 : 迴圈中控制變數 n 沒有改變, 始終都是 1, 所以形成無窮迴圈, 不斷印出 計程很操! 字樣更正 : int n = 1; do Console.WriteLine(" 計程很操!"); ++n; while ( n <= 3 ); 或 (e) (3%) 下列程式片段呼叫函式 Triple 設定變數 b 的數值. class Program static void Main(string[] args) int a = 3; int b = Triple(a); static int Triple(int x) int y = 3x; 答 : 函式 Triple 傳回一個整數, 須以 return 傳送結果給呼叫程式. 更正 : class Program static void Main(string[] args) int a = 3; int b = Triple(a); static int Triple(int x) int y = 3x; 5/14
return y; 5. 試寫出下列程式的輸出 (5%) using System; namespace MidTerm2010Problem5 class Program static void Main(string[] args) int[] a = 4, 5, 6 ; int[] b = a; WhatDoesThisDo(ref a); Console.WriteLine("a[2] = 0, b[2] = 1", a[2], b[2]); static void WhatDoesThisDo(ref int[] x) x[2] = 7; x = new int[4] 8, 9, 0, 1 ; 答 : 6. 試寫出下列程式的輸出 (5%) using System; namespace MidTerm2010Problem6 class Program 6/14
static void Main(string[] args) int[,] x = 2, 3, 2, 1, 1, 2, 1, 3, 2, 1, 1, 1, 2, 1, 3, 3, 2, 1, 1, 2, 1, 2, 3, 2, 1 ; int n = x.getupperbound(0) + 1; int[,] y = new int[n, n]; for (i = 0; i < n; ++i) y[i, 0] = 0; y[i, n-1] = 0; y[0, i] = 0; y[n-1, i] = 0; int j; for (i = 1; i < n - 1; ++i) for (j = 1; j < n - 1; ++j) y[i, j] = Laplacian(x, i, j); for (i = 0; i < n; ++i) for (j = 0; j < n; ++j) Console.Write(y[i, j] + "\t"); Console.WriteLine(); static int Laplacian(int[,] x, int i, int j) int y = x[i - 1, j] + x[i + 1, j] + x[i, j - 1] + 7/14
答 : return y; x[i, j + 1] - 4 x[i, j]; 7. 簡單說明 TDD 的過程 (5%) 答 : (1). 撰寫一個簡單的測試主程式, 呼叫一個待測試的函式 (2). 進行建置, 看它失敗 (3). 增添恰能通過測試的函式程式碼, 並建置 執行 偵錯 (4). 重構 ( 例如使用較有意義的變數名稱 ) 及消除冗餘程式碼 ( 例如將重複 且有獨立價值的程式碼改寫為函式 ), 並建置 執行 除錯 (5). 反覆進行以上步驟 8. / MidTerm2010Problem8 Magic Square skj 4/22/2010 測試規劃 1. / \ 8 1 6 3 5 7 是幻方 8/14
4 9 2 \ / 2. / \ 1 15 14 4 12 6 7 9 是幻方 8 10 11 5 13 3 2 16 \ / 3. / \ 1 2 3 4 5 6 7 8 9 10 11 12 不是幻方 13 14 15 16 \ / 檢驗幻方虛擬碼 函式 IsMagicSquare( 二維陣列 a) 假設方陣以二維陣列 a 表示, 其元素值為 1 到 n 平方的整數 且每個整數均恰好出現一次 ( 不檢查 ) 令數 mm = n(nn+1)/2 為幻方 每行之和, 每列之和, 及兩對角線之和 應有之值 1. 驗證每列之和均等於 M 2. 驗證每行之和均等於 M 3. 驗證主對角線之和等於 M 4. 驗證次對角線之和等於 M 檢查每列之和虛擬碼 函式 RowSumOK( 二維陣列 a, M) 設 a 為 n 乘 n 方陣 1. for(i=0; i<n; ++i) sum = 0 for(j=0; j<n; ++j) 9/14
sum += a[i,j] if( sum 不等於 M ) return false 2. return sum 檢查每行之和虛擬碼 函式 ColumnSumOK( 二維陣列 a, M) 設 a 為 n 乘 n 方陣 1. for(j=0; j<n; ++j) sum = 0 for(i=0; i<n; ++i) sum += a[i,j] if( sum 不等於 M ) return false 2. return sum 檢查主對角線之和虛擬碼 函式 MainDiagnalOK( 二維陣列 a, M) 設 a 為 n 乘 n 方陣 1. sum = 0 2. for(i=0; i<n; ++i) sum += a[i,i] 3. if( sum 等於 M ) return true else return false 檢查次對角線之和虛擬碼 函式 SubDiagnalOK( 二維陣列 a, M) 設 a 為 n 乘 n 方陣 1. sum = 0 2. for(i=0; i<n; ++i) 10/14
sum += a[i,n-1-i] 3. if( sum 等於 M ) return true else return false / using System; using System.Diagnostics; namespace MidTerm2010Problem8 class Program static void Main(string[] args) // 測試 Debug.Assert(Test_1_OK()); Debug.Assert(Test_2_OK()); Debug.Assert(Test_3_OK()); // 主程式 int[,] a = InputArray(); string message = IsMagicSquare(a)? " 此方陣為一幻方 " : " 此方陣非幻方 "; Console.WriteLine(message); static bool Test_1_OK() int[,] a = 8, 1, 6, 3, 5, 7, 4, 9, 2 ; return IsMagicSquare(a); static bool Test_2_OK() 11/14
int[,] a = 1, 15, 14, 4, 12, 6, 7, 9, 8, 10, 11, 5, 13, 3, 2, 16 ; return IsMagicSquare(a); static bool Test_3_OK() int[,] a = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ; return!ismagicsquare(a); static bool IsMagicSquare(int[,] a) int n = a.getupperbound(0) + 1; int mm = n (n n + 1) / 2; if (!RowSumOK(a, n, mm)) return false; if (!ColumnSumOK(a, n, mm)) return false; if (!MainDiagonalOK(a, n, mm)) return false; if (!SubDiagonalOK(a, n, mm)) return false; return true; static bool RowSumOK(int[,] a, int n, int mm) int j; int sum; for (i = 0; i < n; ++i) sum = 0; for (j = 0; j < n; ++j) sum += a[i, j]; if (sum!= mm) return false; 12/14
return true; static bool ColumnSumOK(int[,] a, int n, int mm) int j; int sum; for (j = 0; j < n; ++j) sum = 0; for (i = 0; i < n; ++i) sum += a[i, j]; if (sum!= mm) return false; return true; static bool MainDiagonalOK(int[,] a, int n, int mm) int sum = 0; for(i=0; i<n; ++i) sum += a[i, i]; return (sum == mm); static bool SubDiagonalOK(int[,] a, int n, int mm) int sum = 0; for(i=0; i<n; ++i) sum += a[i, n - 1 - i]; return (sum == mm); 13/14
static int[,] InputArray() Console.Write(" 輸入方陣階數 : "); int n = int.parse(console.readline()); Console.WriteLine( " 輸入方陣元素, 必須在 1 和 0 之間 ", n n); Console.WriteLine(" 不能重複 "); int j; string[] item = new string[n]; int[,] a = new int[n, n]; for (i = 0; i < n; ++i) Console.WriteLine( " 輸入第 0 列之 1 個元素, 以逗點分隔 ", i+1, n); item = (Console.ReadLine()).Split(','); for (j = 0; j < n; ++j) a[i, j] = int.parse(item[j]); // Echo Console.WriteLine(" 輸入之方陣為 :"); for (i = 0; i < n; ++i) for (j = 0; j < n; ++j) Console.Write(a[i, j] + "\t"); Console.WriteLine(); return a; 14/14