# 請寫一支函數, 用來判斷某整數是不是質數 ## 何謂質數? ref : https://zh.wikipedia.org/zh-tw/%E8%B4%A8%E6%95%B0 質數(Prime number),又稱素數,指在大於1的自然數中,除了1和該數自身外,無法被其他自然數整除的數(也可定義為只有1與該數本身兩個正因數的數)。 大於1的自然數若不是質數,則稱之為合數(也稱為合成數)。例如: - 5是個質數,因為其正因數只有1與5。 - 7是個質數,因為其正因數只有1與7。 - 4則是個合數,因為除了1與4外,2也是其正因數。 - 6也是個合數,因為除了1與6外,2與3也是其正因數。 ## 如何設計這支函數? 請思考以下幾點: ### 函數名稱要如何命名? 從上方資訊得知質數的英文是 Prime, 所以, 你可以用它當函數名稱的一部份, 所以, 命名為 `IsPrime, CheckPrime` 這類都是可以考慮的名稱, 但以下的,像 `CheckInt, CheckNumber, MyCheck, CheckIt` 就是糟糕的命名, 因為無法讓人一看就明白這函數要做什麼 ### 函數要傳回什麼型別? 這支函數主要目的是用來判斷某整數是不是質數 如果不傳回值,設計成 `public void IsPrime....` 那麼我們就無從判斷某數值到底是不是質數 如果宣告成傳回 int, 變成 `public int IsPrime....` 傳回 1 表示是質數, 傳回 0 表示非質數, 這樣好嗎? 叫用者會不會以後搞混了, 以為傳回 0 表示是質數? 或者會不會以為傳入 1, -1 才表示結果? 這函數有沒有可能傳回 2, 3, 100, ... ? 如果宣告成傳回 bool, 是不是就好多了呢, true 表示 "是質數" `public bool IsPrime....` ### 命名盡量用正向的名稱,不要用負向的名稱 例如: `public bool IsNotPrime...` 那麼, 請問傳回 true 時, 它表示"是的, 它真的不是質數", 或者"它是質數" 呢? 相較之下, `public bool IsPrime...` 是不是清楚多了呢! ### 函數要傳入什麼參數? 由於題目是判斷一個整數是不是質數, 所以我們可以設計在函數裡面傳入一個整數 `public bool IsPrime(int value)` 它會比設計成 `public bool IsPrime(string value)` 來得好, 我們沒有必要在函數裡才將string 嘗試轉型為 int ### 參數要如何命名? 由於質數的定義是"大於 1 的自然數中,除了 1 和該數自身外,無法被其他自然數整除的數" 因此 `public bool IsPrime(int value)` 裡的" value " 這個參數名稱, 足以暗示叫用者, 應該傳入一個大於1的自然數嗎? 如果命名為 `public bool IsPrime(int positiveInteger)` 其中"positive Integer" 是正整數的意思, 有沒有比 value, 來得容易理解呢? #### 驗證 由於我們希望傳入的是大於1的自然數, 盡管我們已經在參數命名暗示了, 但仍難保有人傳入0或者負數, 因此我們在函數裡仍需要在一開始就先做檢查, 這類檢查我們稱為 precondition checks 請大家養成習慣, 在函數的一開始, 盡量先針對各傳入參數值(也稱為引數)做檢查, 通過之後才開始正式程式, 才不會發生意外的錯誤 ### 參數要用 int 嗎? 接下來, 這要算是題外話了, 各位可以暫時不必做, 在我們從事程式開發的工作, 一直到退休為止, 您一定會一再寫檢查, 例如檢查傳入值是不是正數, 傳入字串是不是 null, 傳入字串是不是合格的 Email 格式, 傳入生日不允許比今天還晚, 傳入的身高不能是負數, .... 其實, 可以平時就設計好一些小的類別, 例如 ``` public class PositiveInteger{ // 只能傳入一個正整數, 否則會丟出例外 } ``` 然後, 我們的函數就宣告成 `public bool IsPrime(PositiveInteger value)` 如此一來, 有沒有更讚呢?!, 在函數裡, 我們不再需要檢查它是不是正整數了, 因為 PositiveInteger 一定是 不過這算進階技巧了, 在各位工作時, 也許同事都覺得這太 over 了, 不能接受, 各位在目前也不必一定要這麼做, 但其實它不失為一個小的做法, 所以一併寫出來供大家參考 # 開工! 提示了這麼多, 大家來寫寫看吧, 看看如何寫一支函數, 判斷傳入值是不是質數, 如何寫出一個好讀易懂的函數