程式中可能會發生的錯誤有三種,分別是語法錯誤 (syntax error) 、執行期間錯誤 (run-time error) 及語意錯誤 (semantic error)
Xcode 會直接幫我們挑出語法錯誤,例如打錯識別字 (identifier) 或關鍵字 (keyword) 等。執行期間錯誤的話比較麻煩,大多數的情況由選擇型態 (optionals) 的機制防範,其他有些則要程式設計師自己寫相關控制機制,不過這些依經驗法則就知道有哪些,像是檔案處理或網路部分。三種錯誤中最麻煩的,就是語意錯誤了,因為有語意錯誤的程式,程式可以順利執行完畢,卻跑出錯誤的結果。
我們的 Encrypt 類別 (class) 目前正是碰到了發生語意錯誤的情況,這是說
y = a * x + b
m = y % n
其中 a 與 b 若是 0 到 9 隨機整數,有些組合成立,可以得到正確結果,有些組合卻會得到錯誤的結果,這是為什麼呢?嗯,好麻煩唷!這樣就得討論好多數學,打斷我們發展程式的腳步,所以我們不打算仔細討論這背後的數學理論,我們繼續測試,直接來找出哪些 a 、 b 組合會得到錯誤的結果吧!
要知道哪些組合可能會發生錯誤,我們就得知道 a 與 b 的值,這不難,印出來就看得到了。我們先把 a 與 b 從 setCode() 中的區域變數 (local variable) 調整為屬性 (property) , Encrypt 類別修改如下
class Encrypt { |
// 英文小寫字母表 |
let alphabet = "abcdefghijklmnopqrstwuvxyz" |
// 密碼表整數陣列 |
var code = Array(arrayLiteral: 26) |
// 把 a 、 b 暫時提升為屬性 |
var a = 0 |
var b = 0 |
// 建構子 |
init() { |
setCode() |
} |
// 設定密碼表 |
func setCode() { |
a = Int(arc4random() % 10) |
b = Int(arc4random() % 10) |
var c = 97 |
var i, x, y, m: Int |
// 以迴圈取得每一個餘數 |
for i = 0; i < 26; i++ { |
x = c |
y = x * a + b |
m = y % 26 |
code.append(m) |
c++ |
} |
// 移除第一個預設值 |
code.removeAtIndex(0) |
} |
// 以下註解化部份略去 |
} |
測試部分加入印出 a 、 b 值,在 Playground 的執行結果如下
結果顯示 a 為偶數或 0 就會跑出不符預期的結果,那我們就把 a 改成不是偶數或 0 好了!公式修改如下
if (a % 2) != 0 {
y = a * x + b
m = y % n
}
這樣 setCode() 在取得 a 、 b 值的部分修改如下
// a 必須是奇數 |
while a % 2 == 0 { |
a = Int(arc4random() % 10) |
b = Int(arc4random() % 10) |
} |
測試部分重新執行,結果如下
肉眼檢查下,似乎只要 a 為奇數,計算出的結果就不會有問題囉!
下個單元我們要開始實作處理編碼的部分,也就是實作 toEncode() 方法 (method) 。
中英文術語對照
語法錯誤 | syntax error |
執行期間錯誤 | run-time error |
語意錯誤 | semantic error |
識別字 | identifier |
關鍵字 | keyword |
選擇型態 | keyword |
類別 | class |
區域變數 | local variable |
屬性 | property |
方法 | method |
沒有留言:
張貼留言