C++ 入門指南 4.01
單元 16 - 繼續測試
軟體生命週期 (software life cycle) 分成三大階段,開發 (development) 、使用 (use) 、修改 (modification) ,接下來便是使用、修改的無限循環
⇓
Use
⇓
Modification
開發階段,自然免不了對需求的分析 (analysis) ,然後設計 (design) 、建置 (implement) ,接著進行測試 (testing)
⇓
Design
⇓
Implement
⇓
Test
其實這順序沒有絕對,「設計」與「建置」可能只是先做個簡單版本,「測試」與「使用」說到底都是實際執行後觀察結果,「修改」等於以之前的基礎再次「設計」與重新「建置」。
我們打算開發的 Encrypt 類別 (class) 的需求已經很清楚,也就是產生一個英文小寫字母的對照字串 (string) ,我們用 code_array 儲存這個字串,然後以 set_code_array() 建立這個字串。
上個單元中,我們將 a 設定為 3 , b 設定為 5 ,順利的跑出一個英文小寫字母的對照字串,現在我們希望把 a 、 b 設定成 0 到 9 之間的隨機整數,這該怎麼做呢?簡單講,就是要有個產生隨機整數的方式,還好標準程式庫 (standard library) 中已經有相關程式 (program) 供我們直接使用,因此我們不需要自己重頭開發。
標準程式庫中 cstdlib 的 rand() 可產生 0 到 RAND_MAX 的擬隨機整數,加一個「擬」的意思是這個數字是模擬出來的,並不算是數學上真正的隨機,不過就我們的需求來講就夠用了,而 RAND_MAX 的數值在 64 位元的 GCC 為 2147483647 。
除了 rand() 外,還需要同在 cstdlib 的 srand() 初始化取得擬隨機數的種子,另外要用 ctime 的 time() 取得現在時間當作 srand() 的參數 (parameter) ,因此原本的實作檔修改如下
// 引入標準程式庫中的 cstdlib 及 ctime #include <cstdlib> // srand(), rand() #include <ctime> // time() // 引入 Encrypt 類別的標頭檔 #include "encrypt01.h" // Encrypt 的建構函數 Encrypt::Encrypt() { // 呼叫 setter 設定 code_array set_code_array(); } // 設定 code_array 的 setter 成員函數 void Encrypt::set_code_array() { // 初始化擬隨機數產生器 srand(time(0)); // 取得 a 、 b 值 int a = rand() % 10; int b = rand() % 10; // 利用公式建立密碼表字串 int x, y, m; char c = 'a'; string s; int i; for (i = 0; i < 26; i++) { x = c; y = x * a + b; m = y % 26; s += m + 97; c++; } // 將建立好的密碼表直接設定給成員變數 code_array = s; } // 回傳密碼表字串的 getter 成員函數 string Encrypt::get_code_array() { return code_array; } /* 《程式語言教學誌》的範例程式 http://kaiching.org/ 檔名:encrypt02.cxx 功能:實作發展中版本的 Encrypt 類別 作者:張凱慶 */
程式開頭先引入 cstdlib 與 ctime
// 引入標準程式庫中的 cstdlib 及 ctime #include <cstdlib> // srand(), rand() #include <ctime> // time()
然後在 set_code_array() 中初始化擬隨機數產生器
// 初始化擬隨機數產生器 srand(time(0));
接者利用 rand() 取得 a 、 b 值
// 取得 a 、 b 值 int a = rand() % 10; int b = rand() % 10;
那就來編譯 (compile) 測試看看囉
看起來還不錯,再多測試幾次看看
居然有一行都是 'g' ,有些是我們要的密碼表沒錯,有一些則不是,那表示我們所用的數學公式有問題,接下來要先修正數學公式。
中英文術語對照 | |
---|---|
分析 | analysis |
類別 | class |
編譯 | compile |
設計 | design |
開發 | development |
建置 | implement |
修改 | modification |
參數 | parameter |
程式 | program |
軟體生命週期 | software life cycle |
標準程式庫 | standard library |
字串 | string |
測試 | testing |
使用 | use |
重點整理 |
---|
1. 軟體的生命週期分成開發、使用、修改三大階段。 |
2. 開發階段就是對需求分析,然後設計、建置、測試等等。 |
3. 標準程式庫中 cstdlib 的 rand() 回傳 0 到 RAND_MAX 的擬隨機整數,並需要以 srand() 初始化取得擬隨機數的種子。 |
4. 設計、建置完軟體的初始版本就進行測試,如果有問題,就重新檢視設計, Encrypt 的數學公式有問題,因此要研究問題出在哪,再回頭修改程式。 |
問題與討論 |
---|
1. 軟體的生命週期分成哪些階段? |
2. 設計軟體的時候,該不該重視使用者的體驗經驗? |
3. 想一想, Encrypt 的數學公式問題可能發生在哪裡?該如何修正呢? |
練習 |
---|
1. 標準程式庫中的 vector 是類似 array 的集合體型態,跟 array 的主要差異是 vector 沒有限制元素總數,另外初始化 vector 的方式也較多,寫一個程式 exercise1601.cxx ,用數種方式建立 vector ,像是 vector<int> 、 vector<int> v2(5) 或是用大括弧設定初始元素等等,然後個別印出一個元素值。 參考程式碼 |
2. 承上題,寫一個程式 exercise1602.cxx ,宣告建立含有 5 個元素的 vector<int> ,然後用迴圈從 0 開示初始化元素,接下來利用 at() 印出第四個元素, back() 印出最後一個元素, front() 印出第一個元素。 參考程式碼 |
3. 承上題,寫一個程式 exercise1603.cxx ,宣告建立含有 5 個元素的 vector<int> ,然後用 empty() 判斷 vector 是否沒有元素,如果沒有元素就印出 -1 ,如果有元素就用迴圈把元素值印在同一行。 參考程式碼 |
4. 承上題,寫一個程式 exercise1604.cxx ,宣告建立含有 5 個元素的 vector<int> ,然後用 clear() 清除所有元素內容,用 empty() 判斷 vector 是否沒有元素,如果沒有元素就印出 -1 ,如果有元素就印出 1 。 參考程式碼 |
5. 承上題, vector 可以用 insert() 插入元素, insert() 需要至少兩個參數,第一個參數是表示索引值的迭代器,第二個參數則是要插入的數值,寫一個程式 exercise1605.cxx ,宣告 vector<int> 變數 v(3, 10) ,然後在 v.begin() 插入整數 30 ,接著印出所有元素內容,繼續在 v.end() 插入整數 40 , v.begin() + 2 插入整數 50 ,並且印出所有元素內容。 參考程式碼 |
6. 電腦中的隨機數被稱為擬隨機數, C++ 中如果用到 C 語言產生擬隨機數的程式,需要引入 <cstdlib> 與 <ctime> ,然後用 srand(time(NULL)) 初始化擬隨機數產生器,就可以用 rand() 取得 0 到 RAND_MAX 之間的隨機整數,寫一個程式 exercise1606.cxx ,用 C 語言產生擬隨機數的方式印出 10 個 0 到 99 之間的隨機整數。 參考程式碼 |
7. 承上題, C++ 產生擬隨機數的程式需要引入 <random> ,然後依序建立隨機設備變數、建立擬隨機數產生器變數、建立隨機分佈變數,然後就可以用隨機分佈變數取得擬隨機數,寫一個程式 exercise1607.cxx ,宣告隨機設備 random_device 型態的變數 r ,然後宣告擬隨機數產生器 default_random_engine 變數 e ,注意要以 r() 當參數,繼續宣告隨機分佈 uniform_int_distribution 型態的變數 n ,注意要用角括弧設定型態 default_random_engine::result_type ,同時設定第一個參數 0 ,第二個參數 99 ,使其產生 0 到 99 之間的隨機數,最後印出 10 個 0 到 99 之間的隨機整數。 參考程式碼 |
8. 承上題,寫一個程式 exercise1608.cxx ,將擬隨機數產生器改成 minstd_rand ,同樣印出 10 個 0 到 99 之間的隨機整數。 參考程式碼 |
9. 承上題,寫一個程式 exercise1609.cxx ,將擬隨機數產生器改成 mt19937 ,同樣印出 10 個 0 到 99 之間的隨機整數。 參考程式碼 |
10. 承上題,寫一個程式 exercise1609.cxx ,將隨機分佈改成 uniform_real_distribution ,印出 10 個 0.0 到 99.99 之間的隨機數。 參考程式碼 |
相關教學影片