第9章模塊化開(kāi)發(fā)_第1頁(yè)
第9章模塊化開(kāi)發(fā)_第2頁(yè)
第9章模塊化開(kāi)發(fā)_第3頁(yè)
第9章模塊化開(kāi)發(fā)_第4頁(yè)
已閱讀5頁(yè),還剩50頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、第9章 模塊化開(kāi)發(fā)自頂向下的分解模塊劃分庫(kù)的設(shè)計(jì)與實(shí)現(xiàn)庫(kù)的應(yīng)用猜硬幣的游戲 功能:提供游戲指南;計(jì)算機(jī)隨機(jī)產(chǎn)生正反面,讓用戶(hù)猜,報(bào)告對(duì)錯(cuò)結(jié)果。重復(fù)此過(guò)程,直到用戶(hù)不想玩了為止。 頂層分解 程序要做兩件事:顯示程序指南;模擬玩游戲的過(guò)程。 main( ) 顯示游戲介紹; 玩游戲;主程序的兩個(gè)步驟是相互獨(dú)立的兩個(gè),沒(méi)有什么聯(lián)系,因此可設(shè)計(jì)成兩個(gè)函數(shù):void prn_instruction()void play() int main() prn_instruction(); play(); return 0;prn_instruction的實(shí)現(xiàn) prn_instruction函數(shù)的實(shí)現(xiàn)非常簡(jiǎn)單,只

2、要一系列的輸出語(yǔ)句把程序指南顯示一下就可以了 void prn_instruction() cout 這是一個(gè)猜硬幣正反面的游戲.n; cout 我會(huì)扔一個(gè)硬幣,你來(lái)猜.n; cout 如果猜對(duì)了,你贏,否則我贏。n;play函數(shù)的實(shí)現(xiàn) Play函數(shù)隨機(jī)產(chǎn)生正反面,讓用戶(hù)猜,報(bào)告對(duì)錯(cuò)結(jié)果,然后詢(xún)問(wèn)是否要繼續(xù)玩 void play() char flag = y; while (flag = Y | flag = y) coin = 生成正反面; 輸入用戶(hù)的猜測(cè); if (用戶(hù)猜測(cè) = coin) 報(bào)告本次猜測(cè)結(jié)果正確; else 報(bào)告本次猜測(cè)結(jié)果錯(cuò)誤; play函數(shù)的細(xì)化生成正反面:如果用0表

3、示正面,1表示反面,那么生成正反面就是隨機(jī)生成0和1兩個(gè)數(shù) 輸入用戶(hù)的猜測(cè)。如果不考慮程序的魯棒性,這個(gè)問(wèn)題也可以直接用一個(gè)輸入語(yǔ)句即可。但想讓程序做得好一點(diǎn),就必須考慮得全面一些。比如,用戶(hù)可以不守規(guī)則,既不輸入0也不輸入1,而是輸入一個(gè)其他值,程序該怎么辦?因此這個(gè)任務(wù)還可以進(jìn)一步細(xì)化,所以再把它抽象成一個(gè)函數(shù)get_call_from_user。 void play() int coin ; char flag = Y; srand(time(NULL); /設(shè)置隨機(jī)數(shù)種子 while (flag = Y | flag =y) coin = rand() * 2 / RAND_MAX;/

4、生成扔硬幣的結(jié)果 if (get_call_from_user() = coin) cout 你贏了; else cout 我贏了; cout flag; get_call_from_user的實(shí)現(xiàn) 該函數(shù)接收用戶(hù)輸入的一個(gè)整型數(shù)。如果輸入的數(shù)不是0或1,則重新輸入,否則返回輸入的值 int get_call_from_user()int guess; / 0 = head, 1 = tail do cout guess; while (guess !=0 & guess !=1) ; return guess;這是一個(gè)猜硬幣正反面的游戲.我會(huì)扔一個(gè)硬幣,你來(lái)猜.如果猜對(duì)了,你贏,否則我贏。輸

5、入你的選擇(0表示正面,1表示反面):1我贏了繼續(xù)玩嗎(Y或y)?y輸入你的選擇(0表示正面,1表示反面):6輸入你的選擇(0表示正面,1表示反面):1你贏了繼續(xù)玩嗎(Y或y)?nPress any key to continue運(yùn)行實(shí)例第9章 模塊化開(kāi)發(fā)自頂向下的分解模塊劃分庫(kù)的設(shè)計(jì)與實(shí)現(xiàn)庫(kù)的應(yīng)用模塊劃分 當(dāng)程序變得更長(zhǎng)的時(shí)候,要在一個(gè)單獨(dú)的源文件中處理如此眾多的函數(shù)會(huì)變得困難 把程序再分成幾個(gè)小的源文件。每個(gè)源文件都包含一組相關(guān)的函數(shù)。一個(gè)源文件被稱(chēng)為一個(gè)模塊。模塊劃分標(biāo)準(zhǔn):塊內(nèi)聯(lián)系盡可能大,塊間聯(lián)系盡可能小 石頭、剪刀、布游戲 游戲規(guī)則布覆蓋石頭石頭砸壞剪刀剪刀剪碎布 游戲的過(guò)程為:游戲

6、者選擇出石頭、剪子或布,計(jì)算機(jī)也隨機(jī)選擇一個(gè),輸出結(jié)果,繼續(xù)游戲,直到游戲者選擇結(jié)束為止。在此過(guò)程中,游戲者也可以閱讀游戲指南或看看當(dāng)前戰(zhàn)況。 第一層的分解 While (用戶(hù)輸入 != quit) switch(用戶(hù)的選擇) case paper, rock, scissor: 機(jī)器選擇; 評(píng)判結(jié)果; 報(bào)告結(jié)果; case game: 顯示目前的戰(zhàn)況; case help: 顯示幫助信息; default: 報(bào)告錯(cuò)誤; 顯示戰(zhàn)況;函數(shù)抽取獲取用戶(hù)輸入selection_by_player獲取機(jī)器輸入selection_by_machine評(píng)判結(jié)果compare報(bào)告結(jié)果并記錄結(jié)果信息repor

7、t顯示目前戰(zhàn)況prn_game_status顯示幫助信息prn_help六個(gè)函數(shù) 枚舉類(lèi)型的定義 為了提高程序的可讀性,我們定義兩個(gè)枚舉類(lèi)型 : enum p_r_s paper, rock, scissor, game, help, quit ; enum outcome win, lose, tie, error ; 模塊劃分 分成四個(gè)模塊:主模塊: main函數(shù)獲取選擇的模塊: selection_by_player和selection_by_machine比較模塊: compare輸出模塊: report、prn_game_status和prn_help函數(shù)Select模塊的設(shè)計(jì)sel

8、ection_by_player從鍵盤(pán)接收用戶(hù)的輸入并返回此輸入值。因此,原型為 p_r_s selection_by_player();selection_by_machine函數(shù)由機(jī)器產(chǎn)生一個(gè)石頭、剪子、布的值,并返回。因此,原型為 p_r_s selection_by_machine();Compare模塊的設(shè)計(jì)compare函數(shù)比較用戶(hù)輸入的值和機(jī)器產(chǎn)生的值,確定輸贏。它要有兩個(gè)參數(shù),都是p_r_s類(lèi)型的,它也應(yīng)該有一個(gè)返回值,就是判斷的結(jié)果 。原型為:outcome compare(p_r_s, p_r_s); print模塊的設(shè)計(jì)prn_help顯示一個(gè)用戶(hù)輸入的指南,告訴用戶(hù)如何

9、輸入他的選擇。因此,它沒(méi)有參數(shù)也沒(méi)有返回值。Report函數(shù)報(bào)告輸贏結(jié)果,并記錄輸贏的次數(shù)。因此它必須有四個(gè)參數(shù):輸贏結(jié)果、輸?shù)拇螖?shù)、贏的次數(shù)和平局的次數(shù),但沒(méi)有返回值。prn_game_status函數(shù)報(bào)告至今為止的戰(zhàn)況,因此需要三個(gè)參數(shù):輸?shù)拇螖?shù)、贏的次數(shù)和平的次數(shù),但沒(méi)有返回值。 print模塊的進(jìn)一步考慮輸?shù)拇螖?shù)、贏的次數(shù)和平局的次數(shù)在Report和prn_game_status兩個(gè)函數(shù)中都出現(xiàn)。Report函數(shù)修改這些變量的值,prn_game_status函數(shù)顯示這些變量的值。這三個(gè)函數(shù)的原型和用戶(hù)期望的原型不一致,用戶(hù)不希望原型中有參數(shù)。輸?shù)拇螖?shù)、贏的次數(shù)和平局的次數(shù)和其他模塊的

10、函數(shù)無(wú)任何關(guān)系,因此可作為該模塊的內(nèi)部狀態(tài)。內(nèi)部狀態(tài)可以作為該模塊的全局變量這樣report和prn_game_status函數(shù)中都不需要這三個(gè)參數(shù)了。 頭文件的設(shè)計(jì)為方便起見(jiàn),我們把所有的符號(hào)常量定義、類(lèi)型定義和函數(shù)原型聲明寫(xiě)在一個(gè)頭文件中,讓每個(gè)模塊都include這個(gè)頭文件。那么,每個(gè)模塊就不必要再寫(xiě)那些函數(shù)的原型聲明了但這樣做又會(huì)引起另一個(gè)問(wèn)題,當(dāng)把這些模塊連接起來(lái)時(shí),編譯器會(huì)發(fā)現(xiàn)這些類(lèi)型定義、符號(hào)常量和函數(shù)原型的聲明在程序中反復(fù)出現(xiàn)多次,解決方法:需要用到一個(gè)新的編譯預(yù)處理命令:#ifndef 標(biāo)識(shí)符 #endif 頭文件的格式#ifndef _name_h#define _name

11、_h 頭文件真正需要寫(xiě)的內(nèi)容#endif石頭、剪子、布游戲的頭文件 / 文件:p_r_s.h/ 本文件定義了兩個(gè)枚舉類(lèi)型,聲明了本程序包括的所有函數(shù)原型#ifndef P_R_S#define P_R_S #include #include #include using namespace std; enum p_r_s paper, rock, scissor, game, help, quit ; enum outcome win, lose, tie, error ; outcome compare(p_r_s player_choice, p_r_s machine_choice);

12、void prn_final_status(); void prn_game_status(); void prn_help(); void report(outcome result); p_r_s selection_by_machine(); p_r_s selection_by_player();#endif主模塊的實(shí)現(xiàn)/文件:main.cpp/ 石頭、剪子、布游戲的主模塊#include p_r_s.hint main(void) outcome result; p_r_s player_choice, machine_choice; / seed the random number

13、 generator srand(time(NULL); while(player_choice = selection_by_player() != quit) switch(player_choice) case paper: case rock: case scissor: machine_choice = selection_by_machine(); result = compare(player_choice, machine_choice); report(result); break; case game: prn_game_status(); break; case help

14、: prn_help(); break; default: cout PROGRAMMER ERROR!nn; exit(1); prn_game_status(); return 0;select模塊的實(shí)現(xiàn) /文件:select.cpp/包括機(jī)器選擇selection_by_machine和/玩家選擇selection_by_player函數(shù)的實(shí)現(xiàn)#include p_r_s.hp_r_s selection_by_machine( ) int select = (rand( ) * 3 / (RAND_MAX + 1); cout I am ; switch(select) case 0:

15、 cout paper. ; break; case 1: cout rock. ; break; case 2: cout scissor. ; break; return (p_r_s) select);p_r_s selection_by_player() char c; p_r_s player_choice; prn_help(); /顯示輸入提示 cout c; switch(c) case p: player_choice = paper; cout you are paper. ; break; case r: player_choice = rock; cout you ar

16、e rock. ; break; case s: player_choice = scissor; cout you are scissor. ;break; case g: player_choice = game; break; case q: player_choice = quit; break; default : player_choice = help; break; return player_choice; Compare模塊的實(shí)現(xiàn) /文件:compare.cpp /包括compare函數(shù)的實(shí)現(xiàn)#include p_r_s.houtcome compare(p_r_s pla

17、yer_choice, p_r_s machine_choice) outcome result; if (player_choice = machine_choice) return tie; switch(player_choice) case paper: result = (machine_choice = rock) ? win : lose; break; case rock: result = (machine_choice = scissor) ? win : lose; break; case scissor: result = (machine_choice = paper

18、) ? win : lose; break; default: cout PROGRAMMER ERROR:Unexpected choice!nn; exit(1); return result; Print模塊的實(shí)現(xiàn) /文件:print.cpp /包括所有與輸出有關(guān)的模塊。/有prn_game_status,prn_help和report函數(shù)#include p_r_s.hint win_cnt = 0, lose_cnt = 0, tie_cnt = 0; /模塊的內(nèi)部狀態(tài)void report(outcome result)switch(result) case win: +win_c

19、nt; cout You win. n; break; case lose: +lose_cnt; cout You lose.n; break; case tie: +tie_cnt; cout A tie.n; break; default: cout PROGRAMMER ERROR!nn; exit(1); void prn_game_status() cout endl ; cout GAME STATUS: endl; cout win: win_cnt endl; cout Lose: lose_cnt endl; cout tie: tie_cnt endl; cout Tot

20、al: win_cnt + lose_cnt + tie_cnt endl;void prn_help() cout endl The following characters can be used:n p for papern r for rockn s for scissorsn g print the game statusn h help, print this listn q quit the gamen;第9章 模塊化開(kāi)發(fā)自頂向下的分解模塊劃分庫(kù)的設(shè)計(jì)與實(shí)現(xiàn)庫(kù)的應(yīng)用設(shè)計(jì)自己的庫(kù) 如果你的工作經(jīng)常要用到一些特殊的工具,你可以設(shè)計(jì)自己的庫(kù)一個(gè)庫(kù)應(yīng)該有一個(gè)主題。一個(gè)庫(kù)中的函數(shù)都應(yīng)該是處

21、理同一類(lèi)問(wèn)題。如標(biāo)準(zhǔn)庫(kù)iostream包含輸入輸出功能,cmath包含數(shù)學(xué)運(yùn)算函數(shù)。我們自己設(shè)計(jì)的庫(kù)也要有一個(gè)主題。設(shè)計(jì)一個(gè)庫(kù)還要考慮到它的通用性。庫(kù)中的功能應(yīng)來(lái)源于某一應(yīng)用,但不局限于該應(yīng)用,而且要高于該應(yīng)用。在某一應(yīng)用程序中提取庫(kù)內(nèi)容時(shí)應(yīng)盡量考慮到兼容更多的應(yīng)用,使其他應(yīng)用程序也能共享這個(gè)庫(kù)。 庫(kù)的設(shè)計(jì)和實(shí)現(xiàn)設(shè)計(jì)庫(kù)的接口:庫(kù)的用戶(hù)必須了解的內(nèi)容,包括庫(kù)中函數(shù)的原型、這些函數(shù)用到的符號(hào)常量和自定義類(lèi)型接口表現(xiàn)為一個(gè)頭文件設(shè)計(jì)庫(kù)中的函數(shù)的實(shí)現(xiàn):表現(xiàn)為一個(gè)源文件庫(kù)的這種實(shí)現(xiàn)方法稱(chēng)為信息隱藏 隨機(jī)函數(shù)庫(kù)的設(shè)計(jì) 庫(kù)的功能 在9.1中,用到了隨機(jī)生成0和1 在9.2中,用到了隨機(jī)生成0和2在自動(dòng)出題中

22、,用到了隨機(jī)生成0和3及隨機(jī)生成0到9用一個(gè)函數(shù)概括:生成low到high之間的隨機(jī)數(shù) int RandomInteger(int low, int high) 初始化函數(shù)RandomInit()實(shí)現(xiàn)設(shè)置隨機(jī)數(shù)種子的功能 在9.1節(jié)中,設(shè)計(jì)了一個(gè)擲硬幣的程序。該程序用到了隨機(jī)數(shù)的一些特性。如果我們的工作經(jīng)常需要用到隨機(jī)數(shù),我們可以把隨機(jī)數(shù)的應(yīng)用寫(xiě)成一個(gè)庫(kù)。 接口文件頭文件的格式:與石頭、剪子、布游戲中的頭文件格式一樣。頭文件中,每個(gè)函數(shù)聲明前應(yīng)該有一段注釋?zhuān)嬖V用戶(hù)如何使用這些函數(shù)。庫(kù)接口的設(shè)計(jì)/文件:Random.h/隨機(jī)函數(shù)庫(kù)的頭文件#ifndef _random_h#define _ra

23、ndom_h/函數(shù):RandomInit/用法:RandomInit()/作用:此函數(shù)初始化隨機(jī)數(shù)種子void RandomInit();/函數(shù):RandomInteger/用法:n = RandomInteger(low, high)/作用:此函數(shù)返回一個(gè)low到high之間的隨機(jī)數(shù),包括low和highint RandomInteger(int low, int high);#endif庫(kù)的實(shí)現(xiàn) 庫(kù)的實(shí)現(xiàn)文件和頭文件的名字是相同的。如頭文件為Random.h,則實(shí)現(xiàn)文件為Random.cpp。 實(shí)現(xiàn)文件的格式:注釋?zhuān)哼@一部分簡(jiǎn)單介紹庫(kù)的功能。include此cpp文件所需的頭文件。每個(gè)實(shí)現(xiàn)

24、要包含自己的頭文件,以便編譯器能檢查函數(shù)定義和函數(shù)原型聲明的一致性。每個(gè)函數(shù)的實(shí)現(xiàn)代碼。在每個(gè)函數(shù)實(shí)現(xiàn)的前面也必須有一段注釋。/文件:Random.cpp/該文件實(shí)現(xiàn)了Random庫(kù)#include #include #include Random.h/函數(shù):RandomInit/該函數(shù)取當(dāng)前系統(tǒng)時(shí)間作為隨機(jī)數(shù)發(fā)生器的種子void RandomInit() srand(time(NULL);/ 函數(shù):RandomInteger/ 該函數(shù)將0到RAND_MAX的區(qū)間的劃分成high - low + 1 個(gè)/ 子區(qū)間。當(dāng)產(chǎn)生的隨機(jī)數(shù)落在第一個(gè)子區(qū)間時(shí),則映射成low。/ 當(dāng)落在最后一個(gè)子區(qū)間時(shí),映

25、射成high。當(dāng)落在第i個(gè)子區(qū)間時(shí)/(i從0到high-low),則映射到low + iint RandomInteger(int low, int high) return (low + (high - low + 1) * rand() / (RAND_MAX + 1); 第9章 模塊化開(kāi)發(fā)自頂向下的分解模塊劃分庫(kù)的設(shè)計(jì)與實(shí)現(xiàn)庫(kù)的應(yīng)用庫(kù)的應(yīng)用 - 龜兔賽跑 動(dòng)物跑動(dòng)類(lèi)型占用時(shí)間跑動(dòng)量烏龜快走50%向前走3點(diǎn)后滑20%向后退6點(diǎn)慢走30%向前走一點(diǎn)兔子睡覺(jué)20%不動(dòng)大后滑20%向后退9點(diǎn)快走10%向前走14點(diǎn)小步跳30%向前走3點(diǎn)慢后滑20%向后退2點(diǎn)龜兔賽跑解題思路分別用變量tortois

26、e和hare代表烏龜和兔子的當(dāng)前位置時(shí)間用秒計(jì)算用隨機(jī)數(shù)來(lái)決定烏龜和兔子在每一秒的動(dòng)作,根據(jù)動(dòng)作決定烏龜和兔子的位置的移動(dòng)跑道的長(zhǎng)度設(shè)為70個(gè)點(diǎn)第一層分解main() int hare = 0, tortoise = 0, timer = 0; /timer是計(jì)時(shí)器,從0開(kāi)始計(jì)時(shí) while (hare RACE_END & tortoise tortoise) cout n hare wins!; else cout n tortoise wins!;抽取函數(shù) 烏龜在這一秒的移動(dòng)距離: int move_tortoise();兔子在這一秒的移動(dòng)距離: int move_hare();輸出當(dāng)前

27、計(jì)時(shí)和兔子烏龜?shù)奈恢?void print_position(int timer, int tortoise, int hare);模塊劃分 主模塊移動(dòng)模塊move_tortoisemove_hare() 輸出模塊print_position 主模塊#include Random.h /包含隨機(jī)數(shù)庫(kù)#include using namespace std;const int RACE_END = 70; /設(shè)置跑道的長(zhǎng)度int move_tortoise();int move_hare();void print_position(int, int, int);int main() int hare = 0, tortoise = 0, timer = 0; RandomInit(); /隨機(jī)數(shù)初始化 cout timer tortoise haren; /輸出表頭 while (h

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論