第9模块化开发.ppt

上传人:sccc 文档编号:5300951 上传时间:2023-06-23 格式:PPT 页数:55 大小:425.53KB
返回 下载 相关 举报
第9模块化开发.ppt_第1页
第1页 / 共55页
第9模块化开发.ppt_第2页
第2页 / 共55页
第9模块化开发.ppt_第3页
第3页 / 共55页
第9模块化开发.ppt_第4页
第4页 / 共55页
第9模块化开发.ppt_第5页
第5页 / 共55页
点击查看更多>>
资源描述

《第9模块化开发.ppt》由会员分享,可在线阅读,更多相关《第9模块化开发.ppt(55页珍藏版)》请在三一办公上搜索。

1、第9章 模块化开发,自顶向下的分解模块划分库的设计与实现库的应用,猜硬币的游戏,功能:提供游戏指南;计算机随机产生正反面,让用户猜,报告对错结果。重复此过程,直到用户不想玩了为止。,顶层分解,程序要做两件事:显示程序指南;模拟玩游戏的过程。,main()显示游戏介绍;玩游戏;,主程序的两个步骤是相互独立的两个,没有什么联系,因此可设计成两个函数:void prn_instruction()void play(),int main()prn_instruction();play();return 0;,prn_instruction的实现,prn_instruction函数的实现非常简单,只要一

2、系列的输出语句把程序指南显示一下就可以了,void prn_instruction()cout 这是一个猜硬币正反面的游戏.n;cout 我会扔一个硬币,你来猜.n;cout 如果猜对了,你赢,否则我赢。n;,play函数的实现,Play函数随机产生正反面,让用户猜,报告对错结果,然后询问是否要继续玩,void play()char flag=y;while(flag=Y|flag=y)coin=生成正反面;输入用户的猜测;if(用户猜测=coin)报告本次猜测结果正确;else 报告本次猜测结果错误;,play函数的细化,生成正反面:如果用0表示正面,1表示反面,那么生成正反面就是随机生成0

3、和1两个数 输入用户的猜测。如果不考虑程序的鲁棒性,这个问题也可以直接用一个输入语句即可。但想让程序做得好一点,就必须考虑得全面一些。比如,用户可以不守规则,既不输入0也不输入1,而是输入一个其他值,程序该怎么办?因此这个任务还可以进一步细化,所以再把它抽象成一个函数get_call_from_user。,void play()int coin;char flag=Y;srand(time(NULL);/设置随机数种子 while(flag=Y|flag=y)coin=rand()*2/RAND_MAX;/生成扔硬币的结果 if(get_call_from_user()=coin)cout f

4、lag;,get_call_from_user的实现,该函数接收用户输入的一个整型数。如果输入的数不是0或1,则重新输入,否则返回输入的值,int get_call_from_user()int guess;/0=head,1=tail do cout guess;while(guess!=0,这是一个猜硬币正反面的游戏.我会扔一个硬币,你来猜.如果猜对了,你赢,否则我赢。输入你的选择(0表示正面,1表示反面):1我赢了继续玩吗(Y或y)?y输入你的选择(0表示正面,1表示反面):6输入你的选择(0表示正面,1表示反面):1你赢了继续玩吗(Y或y)?nPress any key to cont

5、inue,运行实例,第9章 模块化开发,自顶向下的分解模块划分库的设计与实现库的应用,模块划分,当程序变得更长的时候,要在一个单独的源文件中处理如此众多的函数会变得困难 把程序再分成几个小的源文件。每个源文件都包含一组相关的函数。一个源文件被称为一个模块。模块划分标准:块内联系尽可能大,块间联系尽可能小,石头、剪刀、布游戏,游戏规则布覆盖石头石头砸坏剪刀剪刀剪碎布 游戏的过程为:游戏者选择出石头、剪子或布,计算机也随机选择一个,输出结果,继续游戏,直到游戏者选择结束为止。在此过程中,游戏者也可以阅读游戏指南或看看当前战况。,第一层的分解,While(用户输入!=quit)switch(用户的选

6、择)case paper,rock,scissor:机器选择;评判结果;报告结果;case game:显示目前的战况;case help:显示帮助信息;default:报告错误;显示战况;,函数抽取,获取用户输入selection_by_player获取机器输入selection_by_machine评判结果compare报告结果并记录结果信息report显示目前战况prn_game_status显示帮助信息prn_help六个函数,枚举类型的定义,为了提高程序的可读性,我们定义两个枚举类型:enum p_r_s paper,rock,scissor,game,help,quit;enum o

7、utcome win,lose,tie,error;,模块划分,分成四个模块:主模块:main函数获取选择的模块:selection_by_player和selection_by_machine比较模块:compare输出模块:report、prn_game_status和prn_help函数,Select模块的设计,selection_by_player从键盘接收用户的输入并返回此输入值。因此,原型为 p_r_s selection_by_player();selection_by_machine函数由机器产生一个石头、剪子、布的值,并返回。因此,原型为 p_r_s selection_by

8、_machine();,Compare模块的设计,compare函数比较用户输入的值和机器产生的值,确定输赢。它要有两个参数,都是p_r_s类型的,它也应该有一个返回值,就是判断的结果。原型为:outcome compare(p_r_s,p_r_s);,print模块的设计,prn_help显示一个用户输入的指南,告诉用户如何输入他的选择。因此,它没有参数也没有返回值。Report函数报告输赢结果,并记录输赢的次数。因此它必须有四个参数:输赢结果、输的次数、赢的次数和平局的次数,但没有返回值。prn_game_status函数报告至今为止的战况,因此需要三个参数:输的次数、赢的次数和平的次数,

9、但没有返回值。,print模块的进一步考虑,输的次数、赢的次数和平局的次数在Report和prn_game_status两个函数中都出现。Report函数修改这些变量的值,prn_game_status函数显示这些变量的值。这三个函数的原型和用户期望的原型不一致,用户不希望原型中有参数。输的次数、赢的次数和平局的次数和其他模块的函数无任何关系,因此可作为该模块的内部状态。内部状态可以作为该模块的全局变量这样report和prn_game_status函数中都不需要这三个参数了。,头文件的设计,为方便起见,我们把所有的符号常量定义、类型定义和函数原型声明写在一个头文件中,让每个模块都includ

10、e这个头文件。那么,每个模块就不必要再写那些函数的原型声明了但这样做又会引起另一个问题,当把这些模块连接起来时,编译器会发现这些类型定义、符号常量和函数原型的声明在程序中反复出现多次,解决方法:需要用到一个新的编译预处理命令:#ifndef 标识符#endif,头文件的格式,#ifndef _name_h#define _name_h 头文件真正需要写的内容#endif,石头、剪子、布游戏的头文件,/文件:p_r_s.h/本文件定义了两个枚举类型,声明了本程序包括的所有函数原型#ifndef P_R_S#define P_R_S#include#include#include using na

11、mespace 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);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();#endi

12、f,主模块的实现,/文件:main.cpp/石头、剪子、布游戏的主模块#include p_r_s.hint main(void)outcome result;p_r_s player_choice,machine_choice;/seed the random number generator srand(time(NULL);,while(player_choice=selection_by_player()!=quit)switch(player_choice)case paper:case rock:case scissor:machine_choice=selection_by_ma

13、chine();result=compare(player_choice,machine_choice);report(result);break;case game:prn_game_status();break;case help:prn_help();break;default:cout PROGRAMMER ERROR!nn;exit(1);prn_game_status();return 0;,select模块的实现,/文件:select.cpp/包括机器选择selection_by_machine和/玩家选择selection_by_player函数的实现#include p_r_

14、s.hp_r_s selection_by_machine()int select=(rand()*3/(RAND_MAX+1);cout I am;switch(select)case 0: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=pap

15、er;cout you are paper.;break;case r:player_choice=rock;cout you are 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模块的实现,/文件:compare.cpp/包括compare函数的实现#

16、include p_r_s.houtcome compare(p_r_s player_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=p

17、aper)?win:lose;break;default:cout PROGRAMMER ERROR:Unexpected choice!nn;exit(1);return result;,Print模块的实现,/文件:print.cpp/包括所有与输出有关的模块。/有prn_game_status,prn_help和report函数#include p_r_s.hint win_cnt=0,lose_cnt=0,tie_cnt=0;/模块的内部状态,void report(outcome result)switch(result)case win:+win_cnt;cout You win.

18、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 Total:win_cnt+lose_cnt+tie_cnt endl;,void pr

19、n_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章 模块化开发,自顶向下的分解模块划分库的设计与实现库的应用,设计自己的库,如果你的工作经常要用到一些特殊的工具,你可以设计自己的库一个库应该有一个主题。一个库中的函数都应该是处理同一类问题。如标准库iostream包含输入输出功能,cmath包含数学运算函数。我们

20、自己设计的库也要有一个主题。设计一个库还要考虑到它的通用性。库中的功能应来源于某一应用,但不局限于该应用,而且要高于该应用。在某一应用程序中提取库内容时应尽量考虑到兼容更多的应用,使其他应用程序也能共享这个库。,库的设计和实现,设计库的接口:库的用户必须了解的内容,包括库中函数的原型、这些函数用到的符号常量和自定义类型接口表现为一个头文件设计库中的函数的实现:表现为一个源文件库的这种实现方法称为信息隐藏,随机函数库的设计,库的功能 在9.1中,用到了随机生成0和1 在9.2中,用到了随机生成0和2在自动出题中,用到了随机生成0和3及随机生成0到9用一个函数概括:生成low到high之间的随机数

21、 int RandomInteger(int low,int high)初始化函数RandomInit()实现设置随机数种子的功能,在9.1节中,设计了一个掷硬币的程序。该程序用到了随机数的一些特性。如果我们的工作经常需要用到随机数,我们可以把随机数的应用写成一个库。,接口文件,头文件的格式:与石头、剪子、布游戏中的头文件格式一样。头文件中,每个函数声明前应该有一段注释,告诉用户如何使用这些函数。,库接口的设计,/文件:Random.h/随机函数库的头文件#ifndef _random_h#define _random_h/函数:RandomInit/用法:RandomInit()/作用:此函

22、数初始化随机数种子void RandomInit();/函数:RandomInteger/用法:n=RandomInteger(low,high)/作用:此函数返回一个low到high之间的随机数,包括low和highint RandomInteger(int low,int high);#endif,库的实现,库的实现文件和头文件的名字是相同的。如头文件为Random.h,则实现文件为Random.cpp。实现文件的格式:注释:这一部分简单介绍库的功能。include此cpp文件所需的头文件。每个实现要包含自己的头文件,以便编译器能检查函数定义和函数原型声明的一致性。每个函数的实现代码。在每

23、个函数实现的前面也必须有一段注释。,/文件:Random.cpp/该文件实现了Random库#include#include#include Random.h/函数:RandomInit/该函数取当前系统时间作为随机数发生器的种子void RandomInit()srand(time(NULL);,/函数:RandomInteger/该函数将0到RAND_MAX的区间的划分成high-low+1 个/子区间。当产生的随机数落在第一个子区间时,则映射成low。/当落在最后一个子区间时,映射成high。当落在第i个子区间时/(i从0到high-low),则映射到low+iint RandomInt

24、eger(int low,int high)return(low+(high-low+1)*rand()/(RAND_MAX+1);,第9章 模块化开发,自顶向下的分解模块划分库的设计与实现库的应用,库的应用-龟兔赛跑,龟兔赛跑解题思路,分别用变量tortoise和hare代表乌龟和兔子的当前位置时间用秒计算用随机数来决定乌龟和兔子在每一秒的动作,根据动作决定乌龟和兔子的位置的移动跑道的长度设为70个点,第一层分解,main()int hare=0,tortoise=0,timer=0;/timer是计时器,从0开始计时 while(hare tortoise)cout n hare wins

25、!;else cout n tortoise wins!;,抽取函数,乌龟在这一秒的移动距离:int move_tortoise();兔子在这一秒的移动距离:int move_hare();输出当前计时和兔子乌龟的位置 void print_position(int timer,int tortoise,int hare);,模块划分,主模块移动模块move_tortoisemove_hare()输出模块print_position,主模块,#include Random.h/包含随机数库#include using namespace std;const int RACE_END=70;/设

26、置跑道的长度int move_tortoise();int move_hare();void print_position(int,int,int);,int main()int hare=0,tortoise=0,timer=0;RandomInit();/随机数初始化 cout tortoise)cout n hare wins!n;else cout n tortoise wins!n;return 0;,如何用随机数模拟概率,以乌龟为例,它的三种情况和概率如下:为此我们可以生成0-9之间的随机数,当生成的随机数为0-4时,认为是第一种情况,5-6是第二种情况,7-9是第三种情况。这样就

27、可以根据生成的随机数确定发生的事件,Move模块,/文件名:move.cpp#include Random.h/本模块用到了随机函数库int move_tortoise()int probability=RandomInteger(0,9);/产生0到9之间的随机数 if(probability 5)return 3;/快走 else if(probability 7)return-6;/后滑 else return 1;/慢走,int move_hare()int probability=RandomInteger(0,9);if(probability 2)return 0;/睡觉 els

28、e if(probability 4)return-9;/大后滑 else if(probability 5)return 14;/快走 else if(probability 8)return 3;/小步跳 else return-2;/慢后滑,Print模块,/文件名:print.cpp#include using namespace std;void print_position(int timer,int t,int h)if(timer%6=0)cout endl;/每隔6秒空一行 cout timer t t t h n;,总结,本章介绍了如何利用结构化程序设计的技术来解决一个大问题。利用结构化程序设计的技术可以容易地将一个应用分成若干个独立的模块来构建整个程序。如何在模块中保存内部状态如何从程序中抽取出库以及如何设计和使用库,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/施工/环境 > 农业报告


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号