通識計算機程式設計期中考試題參考解答, 4/17/2009 1. 撰寫一或數個 C# 敘述達成下列要求 : ( 假設 using System; 敘述已經包含於程式中 ) (a) 宣告 int 變數 x, bool 變數 b, double 常數 F = 7.0. (3%) int x; bool b; const double F = 7.0; (b) 在螢幕顯示一行字, 要求使用者輸入一個整數. (3%) Console.WriteLine(" 輸入一個整數 "); (c) 自鍵盤讀入一個整數., 並將其值存入已宣告之 int 變數 x (3%) x = Convert.ToInt16(Console.ReadLine()); 或 x = int.parse(console.readline()); (d) 令已宣告之 bool 變數 b 等於邏輯敘述 x < F 的結果. (3%) b = x < F; (e) 若.b 為真, 在螢幕顯示 x <= F 否則印出 x > F (3%) if (b) Console.WriteLine("x <= F"); else Console.WriteLine("x > F"); 或 1/14
string message = b? "x <= F" : "x > F"; Console.WriteLine(message); 2. 撰寫一或數個 C# 敘述達成下列要求 : ( 假設 using System; 敘述已經包含於程式中 ) (a) 使用遞減算子 -- 將已宣告設值之 int 變數 m 先減 1 後, 再設定 (assign) 給他處已宣告之 int 變數 k (3%) k = --m; (b) 令他處已宣告之 int 變數 r 等於他處已宣告設值之 int 變數 p 除以 10 的餘數 (3%) r = p % 10; (c) 宣告 double 變數 u, 並令其值為 double 變數 t 的平方根 (3%) double u = Math.Sqrt(t); (d) 宣告 string 變數 s, 利用三元運算子使其在他處已宣告設值之 double 變數 grade 大於等於 60 時等於 及格, 反之則等於 不及格 (3%) string s = (grade >= 60.0)? " 及格 " : " 不及格 "; (e) 宣告變數 c 為 char 型別, 並令其值為定位鍵 (tab) 字元 (3%) char c = '\t'; 3. 構想一個類別 Cube 如下圖之 UML 符號, 撰寫一或數個 C# 敘述達成下列要求 : ( 假設 using System; 敘述已經包含於程式中 ): 其中 (a) (b) (c) 要求寫測試程式片段,(d) 要求寫一完整類別程式 假設 Cube 類別程式碼中沒有多載建構式 2/14
(a) 產生一個 Cube 物件, 宣告命名為 cube (3%) Cube cb = new Cube(); (b) 利用屬性 Side, 可以設定或取得產生之立方體物件的邊長, 試寫一敘述設定 cube 的邊長為 2 (3%) cb.side = 2; (c).cube 內有一個函式 Volume 可以傳回產生之立方體物件的體積, 試寫一敘述呼叫 cube 的 Volume 函式計算體積, 並將結果存入一他處已宣告之 double 變數 v (3%) v = cb.volume(); (d) 撰寫完整之 Cube 類別程式 (6%) class Cube private int side; public int Side get return side; set side = value; public int Volume() return side * side * side; 4. 找出以下程式片段之錯誤, 並予更正. (a) (3%) const int L; L = 30; 常數宣告時應同時設定其值, 故應改為 const int L = 30; 3/14
(b) (3%) enum Status FAIL = 0, PASS = 1 Status st = PASS; 列舉型別之值使用時須加註列舉型別名稱, 故最後一行應改為 Status st = Status.PASS; (c) (3%) 以下程式片段應計算 1 到 10 加總的和. int i; int sum = 0; for ( i=1; i < 10; ++i ) sum += i; 這是 off-by-one error, 迴圈只加到 9, 沒有把 10 算進去 應改為 int i; int sum = 0; for (i = 1; i <= 10; ++i) sum += i; (d) (3%) 以下程式片段應印出 計程好累! 字樣 3 次. int n = 0; while ( n < 3 ) Console.WriteLine( 計程好累! ); 迴圈內控制變數不會改變其值, 造成無窮迴圈 應改為 int n = 0; while ( n < 3 ) 4/14
Console.WriteLine(" 計程好累!");; ++n; 或 int n = 0; while ( n < 3 ) ++n; Console.WriteLine(" 計程好累!");; (e) (3%) 下列程式片段呼叫函式 GetValues 得到變數 a 與 b 的新數值. int a; int b; GetValues( ref a, ref b ); static void GetValues( ref int a, ref int b ) a = 3; b = 5; 使用傳址引數必須先設定其值, 否則就應改用 out 引數 所以應改為 int a = 0; int b = 0; GetValues(ref a, ref b); 5/14
static void GetValues(ref int a, ref int b) a = 3; b = 5; 或 int a; int b; GetValues(out a, out b); static void GetValues(out int a, out int b) a = 3; b = 5; 5. 試寫出下列程式的輸出 (3%) using System; namespace MidTerm2009Problem5 struct SPoint2D public int x; public int y; public SPoint2D(int x, int y) this.x = x; this.y = y; 6/14
class CPoint2D public int x; public int y; public CPoint2D() x = 0; y = 0; public CPoint2D(int x, int y) this.x = x; this.y = y; SPoint2D spt1 = new SPoint2D(1, 2); SPoint2D spt2 = new SPoint2D(); SPoint2D spt3 = new SPoint2D(); spt2 = spt1; spt3 = spt1; Console.WriteLine("sPt1 = (0, 1)", spt1.x, spt1.y); Console.WriteLine("sPt2 = (0, 1)", spt2.x, spt2.y); Console.WriteLine("sPt3 = (0, 1)", spt3.x, spt3.y); CPoint2D cpt1 = new CPoint2D(1, 2); CPoint2D cpt2 = new CPoint2D(); CPoint2D cpt3 = new CPoint2D(); cpt2 = cpt1; cpt3 = cpt1; 7/14
Console.WriteLine("cPt1 = (0, 1)", cpt1.x, cpt1.y); Console.WriteLine("cPt2 = (0, 1)", cpt2.x, cpt2.y); Console.WriteLine("cPt3 = (0, 1)", cpt3.x, cpt3.y); spt1.x = 5; spt1.y = 6; spt2.x = 7; spt2.y = 8; Console.WriteLine("sPt1 = (0, 1)", spt1.x, spt1.y); Console.WriteLine("sPt2 = (0, 1)", spt2.x, spt2.y); Console.WriteLine("sPt3 = (0, 1)", spt3.x, spt3.y); cpt1.x = 5; cpt1.y = 6; cpt2.x = 7; cpt2.y = 8; Console.WriteLine("cPt1 = (0, 1)", cpt1.x, cpt1.y); Console.WriteLine("cPt2 = (0, 1)", cpt2.x, cpt2.y); Console.WriteLine("cPt3 = (0, 1)", cpt3.x, cpt3.y); 如下圖 8/14
6. 舉一個課堂與講義所授以外的例子, 以台大一般科系初學程式設計的同學應該能了解的程度為準, 解釋什麼是物件? 什麼是類別? (6%) ( 略 ) 7. 簡單說明 工程方法 如何用來開發程式 (6%) ( 參考 物件導向虛擬程式設計 講義,4.3 節 ) 8. 寫一程式檢驗所給三角形之三邊長是否構成一個直角三角形 本題滿分 25 分, 全部程式寫成一個大 Main 函式, 不區分函式及類別者, 最高得 20 分 ; 善用函式者, 最高得 22 分 ; 善用自創類別者, 最高得 24 分, 善用自創類別及 Debug.Assert 敘述設計者, 最高得 25 分 (25%) 寫成一個大 Main 函式, 不區分函式及類別 : using System; namespace MidTerm2009Problem8 9/14
Console.WriteLine(" 輸入三角形第一邊長 "); double a = double.parse(console.readline()); Console.WriteLine(" 輸入三角形第二邊長 "); double b = double.parse(console.readline()); Console.WriteLine(" 輸入三角形第三邊長 "); double c = double.parse(console.readline()); const double EPSILON = 1.0e-4; if (Math.Abs(a * a + b * b - c * c) < EPSILON Math.Abs(b * b + c * c - a * a) < EPSILON Math.Abs(c * c + a * a - b * b) < EPSILON) Console.WriteLine(" 大約是直角三角形 "); else Console.WriteLine(" 不是直角三角形 "); 使用函式 using System; namespace MidTerm2009Problem8 Console.WriteLine(" 輸入三角形第一邊長 "); double a = double.parse(console.readline()); Console.WriteLine(" 輸入三角形第二邊長 "); double b = double.parse(console.readline()); Console.WriteLine(" 輸入三角形第三邊長 "); double c = double.parse(console.readline()); if ( IsRTriangle( a, b, c ) ) 10/14
Console.WriteLine(" 大約是直角三角形 "); else Console.WriteLine(" 不是直角三角形 "); public static bool IsRTriangle(double a, double b, double c) const double EPSILON = 1.0e-4; bool result = Math.Abs(a * a + b * b - c * c) < EPSILON Math.Abs(b * b + c * c - a * a) < EPSILON Math.Abs(c * c + a * a - b * b) < EPSILON; return result; 使用自創類別 using System; namespace MidTerm2009Problem8 Console.WriteLine(" 輸入三角形第一邊長 "); double a = double.parse(console.readline()); Console.WriteLine(" 輸入三角形第二邊長 "); double b = double.parse(console.readline()); Console.WriteLine(" 輸入三角形第三邊長 "); double c = double.parse(console.readline()); 11/14
if ( RTriangleTester.IsRTriangle( a, b, c ) ) Console.WriteLine(" 大約是直角三角形 "); else Console.WriteLine(" 不是直角三角形 "); class RTriangleTester public static bool IsRTriangle( double a, double b, double c ) const double EPSILON = 1.0e-4; bool result = Math.Abs(a * a + b * b - c * c) < EPSILON Math.Abs(b * b + c * c - a * a) < EPSILON Math.Abs(c * c + a * a - b * b) < EPSILON; return result; 併用自創類別及 Debug.Assert 敘述 using System; using System.Diagnostics; namespace MidTerm2009Problem8 // 執行程式前先測試已知範例是否正確 Debug.Assert( RTriangleTesterTest.OK() ); 12/14
Console.WriteLine(" 輸入三角形第一邊長 "); double a = double.parse(console.readline()); Console.WriteLine(" 輸入三角形第二邊長 "); double b = double.parse(console.readline()); Console.WriteLine(" 輸入三角形第三邊長 "); double c = double.parse(console.readline()); if ( RTriangleTester.IsRTriangle( a, b, c ) ) Console.WriteLine(" 大約是直角三角形 "); else Console.WriteLine(" 不是直角三角形 "); class RTriangleTesterTest public static bool OK() bool success1 = RTriangleTester.IsRTriangle( 3.0, 4.0, 5.0); bool success2 = RTriangleTester.IsRTriangle( 13.0, 5.0, 12.0); bool success3 = RTriangleTester.IsRTriangle( 1.0, 1.41421, 1.0); bool success4 = RTriangleTester.IsRTriangle( 1.0, 1.41421, 1.732051); bool success5 =!RTriangleTester.IsRTriangle( 4.0, 4.0, 4.0); bool success6 =!RTriangleTester.IsRTriangle( 8.0, 8.0, 5.0); return success1 && success2 && success3 && success4 && success5 && success6; 13/14
class RTriangleTester public static bool IsRTriangle( double a, double b, double c ) const double EPSILON = 1.0e-4; bool result = Math.Abs(a * a + b * b - c * c) < EPSILON Math.Abs(b * b + c * c - a * a) < EPSILON Math.Abs(c * c + a * a - b * b) < EPSILON; return result; 14/14