編譯器 (compiler) 會直接幫我們挑出語法錯誤,例如打錯識別字 (identifier) 名稱或是漏打分號等等。執行期間錯誤的話, C# 另有例外處理 (exception handling) 的機制,使我們可處理如開啟指定檔名的檔案,然而檔案卻不存在的情況。三種錯誤中最麻煩的,就是語意錯誤了,因為有語意錯誤的程式,程式可以順利執行完畢,卻跑出錯誤的結果。
我們的 Encrypt 類別 (class) 目前正是碰到了發生語意錯誤的情況,這是說
y = a * x + b
m = y % n
r = m + diff
其中 a 與 b 若是 1 到 9 隨機整數,有些組合成立,可以得到正確結果,有些組合卻會得到錯誤的結果,這是為什麼呢?嗯,好麻煩唷!這樣就得討論好多數學,打斷我們發展程式的腳步,因此我們不會也不打算仔細討論這背後的數學理論,我們繼續測試,直接來找出哪些組合會得到錯誤的結果吧!
要知道哪些組合可能會發生錯誤,我們就得知道 a 與 b 的值,這不難,印出來就看得到了,我們將 setArray() 加入印出 a 、 b 值的陳述 (statement) ,因此新的 encrypt00.cs 如下
class Encrypt { string cArray; public void setArray() { System.Random r = new System.Random(); int a = r.Next(1, 10); int b = r.Next(1, 10); System.Console.Write("a: " + a + ", b: " + b + ", "); int x, y, m; char c = 'a'; int i; System.Text.StringBuilder s = new System.Text.StringBuilder(); for (i = 0; i < 26; i++) { x = c; y = x * a + b; m = y % 26; s.Append((char) (m + 97)); c++; } this.cArray = s.ToString(); } static void Main() { for (int i = 0; i < 16; i++) { Encrypt e = new Encrypt(); e.setArray(); System.Console.WriteLine("e" + i + ": "+ e.cArray); System.Threading.Thread.Sleep(1000); } } } /* 《程式語言教學誌》的範例程式 http://pydoing.blogspot.com/ 檔名:encrypt00.cs 功能:示範 C# 程式 作者:張凱慶 時間:西元 2012 年 10 月 */
我們用到 System.Console.Write() ,這是另外一個在命令列印出訊息的方法,它與 println() 的差別是不會印出新行符號,也就是 '\n' 。
來編譯執行看看囉
我們可以發現以下這幾組 (a, b) 出現問題
(4, 8) (2, 5) (4, 5)
共通的特點 a 是偶數,所以 a 不能是偶數嗎?我們繼續改寫進行測試
class Encrypt { string cArray; public void setArray() { System.Random r = new System.Random(); int a = 0; int b = 0; // 限定 a 為偶數 while (a % 2 == 0) { a = r.Next(1, 10); b = r.Next(1, 10); } System.Console.Write("a: " + a + ", b: " + b + ", "); int x, y, m; char c = 'a'; int i; System.Text.StringBuilder s = new System.Text.StringBuilder(); for (i = 0; i < 26; i++) { x = c; y = x * a + b; m = y % 26; s.Append((char) (m + 97)); c++; } this.cArray = s.ToString(); } static void Main() { for (int i = 0; i < 16; i++) { Encrypt e = new Encrypt(); e.setArray(); System.Console.WriteLine("e" + i + ": "+ e.cArray); System.Threading.Thread.Sleep(1000); } } } /* 《程式語言教學誌》的範例程式 http://pydoing.blogspot.com/ 檔名:encrypt00.cs 功能:示範 C# 程式 作者:張凱慶 時間:西元 2012 年 10 月 */
編譯後執行,如下
這裡
int a = 0; int b = 0; // 限定 a 為偶數 while (a % 2 == 0) { a = r.Next(1, 10); b = r.Next(1, 10); }
a % 2 計算出 a 除以 2 的餘數,如果 a 除以 2 等於 0 ,那麼意味著 a 為 0 或偶數。我們用 a % 2 等於 0 當條件 (condition) ,迴圈 (loop) 在 a 為奇數時就會結束。
嗯,我們用肉眼檢查,似乎只要 a 為奇數,計算出的結果就不會有問題。因此,公式應修正如下
y = a * x + b // a % 2 != 0
m = y % n
r = m + diff
也就是在 a % 2 不等於 0 之時,公式才成立。嗯,目前我們都是修改 setArray() 進行測試,如果我們希望 Encrypt 更完備, Encrypt 的屬性 (property) 設定應該要放在建構子 (constructor) 之中。
中英文術語對照 | |
---|---|
語法錯誤 | syntax error |
執行期間錯誤 | run-time error |
語意錯誤 | sematic error |
編譯器 | compiler |
識別字 | identifier |
例外處理 | exception handling |
類別 | class |
陳述 | statement |
條件 | condition |
迴圈 | loop |
屬性 | property |
建構子 | constructor |
您可以繼續參考
軟體開發
相關目錄
回 C# 入門指南
回 C# 教材
回首頁
參考資料
http://msdn.microsoft.com/zh-tw/library/ms173109%28v=vs.80%29.aspx
http://msdn.microsoft.com/zh-tw/library/x9afc042.aspx
http://msdn.microsoft.com/zh-tw/library/ms229036%28v=vs.80%29.aspx
http://msdn.microsoft.com/zh-tw/library/0b0thckt.aspx
1 則留言:
「我們用到 System.Console.Write() ,這是另外一個在命令列印出訊息的方法,它與 println() 的差別是不會印出新行符號,也就是 '\n' 。」
println() 是 python 的吧!?
張貼留言