C++ 入門指南 4.01

單元 16 - 繼續測試

-unit16-

軟體生命週期 (software life cycle) 分成三大階段,開發 (development) 使用 (use) 修改 (modification) ,接下來便是使用、修改的無限循環

Development

Use

Modification

開發階段,自然免不了對需求的分析 (analysis) ,然後設計 (design) 建置 (implement) ,接著進行測試 (testing)

Analysis

Design

Implement

Test

其實這順序沒有絕對,「設計」與「建置」可能只是先做個簡單版本,「測試」與「使用」說到底都是實際執行後觀察結果,「修改」等於以之前的基礎再次「設計」與重新「建置」。

我們打算開發的 Encrypt 類別 (class) 的需求已經很清楚,也就是產生一個英文小寫字母的對照字串 (string) ,我們用 code_array 儲存這個字串,然後以 set_code_array() 建立這個字串。

上個單元中,我們將 a 設定為 3b 設定為 5 ,順利的跑出一個英文小寫字母的對照字串,現在我們希望把 ab 設定成 09 之間的隨機整數,這該怎麼做呢?簡單講,就是要有個產生隨機整數的方式,還好標準程式庫 (standard library) 中已經有相關程式 (program) 供我們直接使用,因此我們不需要自己重頭開發。

標準程式庫中 cstdlibrand() 可產生 0RAND_MAX 的擬隨機整數,加一個「擬」的意思是這個數字是模擬出來的,並不算是數學上真正的隨機,不過就我們的需求來講就夠用了,而 RAND_MAX 的數值在 64 位元的 GCC 為 2147483647

除了 rand() 外,還需要同在 cstdlibsrand() 初始化取得擬隨機數的種子,另外要用 ctimetime() 取得現在時間當作 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 類別
   作者:張凱慶 */

程式開頭先引入 cstdlibctime

// 引入標準程式庫中的 cstdlib 及 ctime
#include <cstdlib> // srand(), rand()
#include <ctime>   // time()

然後在 set_code_array() 中初始化擬隨機數產生器

    // 初始化擬隨機數產生器
    srand(time(0));

接者利用 rand() 取得 ab

    // 取得 a 、 b 值
    int a = rand() % 10;
    int b = rand() % 10;

那就來編譯 (compile) 測試看看囉

-encrypt0201-

看起來還不錯,再多測試幾次看看

-encrypt0202-

居然有一行都是 'g' ,有些是我們要的密碼表沒錯,有一些則不是,那表示我們所用的數學公式有問題,接下來要先修正數學公式。

中英文術語對照
分析analysis
類別class
編譯compile
設計design
開發development
建置implement
修改modification
參數parameter
程式program
軟體生命週期software life cycle
標準程式庫standard library
字串string
測試testing
使用use
重點整理
1. 軟體的生命週期分成開發、使用、修改三大階段。
2. 開發階段就是對需求分析,然後設計、建置、測試等等。
3. 標準程式庫中 cstdlibrand() 回傳 0RAND_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() 插入整數 40v.begin() + 2 插入整數 50 ,並且印出所有元素內容。 參考程式碼
6. 電腦中的隨機數被稱為擬隨機數, C++ 中如果用到 C 語言產生擬隨機數的程式,需要引入 <cstdlib><ctime> ,然後用 srand(time(NULL)) 初始化擬隨機數產生器,就可以用 rand() 取得 0RAND_MAX 之間的隨機整數,寫一個程式 exercise1606.cxx ,用 C 語言產生擬隨機數的方式印出 10 個 099 之間的隨機整數。 參考程式碼
7. 承上題, C++ 產生擬隨機數的程式需要引入 <random> ,然後依序建立隨機設備變數、建立擬隨機數產生器變數、建立隨機分佈變數,然後就可以用隨機分佈變數取得擬隨機數,寫一個程式 exercise1607.cxx ,宣告隨機設備 random_device 型態的變數 r ,然後宣告擬隨機數產生器 default_random_engine 變數 e ,注意要以 r() 當參數,繼續宣告隨機分佈 uniform_int_distribution 型態的變數 n ,注意要用角括弧設定型態 default_random_engine::result_type ,同時設定第一個參數 0 ,第二個參數 99 ,使其產生 099 之間的隨機數,最後印出 10099 之間的隨機整數。 參考程式碼
8. 承上題,寫一個程式 exercise1608.cxx ,將擬隨機數產生器改成 minstd_rand ,同樣印出 10099 之間的隨機整數。 參考程式碼
9. 承上題,寫一個程式 exercise1609.cxx ,將擬隨機數產生器改成 mt19937 ,同樣印出 10099 之間的隨機整數。 參考程式碼
10. 承上題,寫一個程式 exercise1609.cxx ,將隨機分佈改成 uniform_real_distribution ,印出 100.099.99 之間的隨機數。 參考程式碼

相關教學影片

上一頁 單元 15 - 實作 set_code_array()
回 C++ 入門指南 4.01 目錄
下一頁 單元 17 - 修正後的數學公式
回 C++ 教材
回程式語言教材首頁