计算机程序设计基础 第五章程序组织与软件开发方法.ppt

上传人:小飞机 文档编号:6342633 上传时间:2023-10-18 格式:PPT 页数:73 大小:231KB
返回 下载 相关 举报
计算机程序设计基础 第五章程序组织与软件开发方法.ppt_第1页
第1页 / 共73页
计算机程序设计基础 第五章程序组织与软件开发方法.ppt_第2页
第2页 / 共73页
计算机程序设计基础 第五章程序组织与软件开发方法.ppt_第3页
第3页 / 共73页
计算机程序设计基础 第五章程序组织与软件开发方法.ppt_第4页
第4页 / 共73页
计算机程序设计基础 第五章程序组织与软件开发方法.ppt_第5页
第5页 / 共73页
点击查看更多>>
资源描述

《计算机程序设计基础 第五章程序组织与软件开发方法.ppt》由会员分享,可在线阅读,更多相关《计算机程序设计基础 第五章程序组织与软件开发方法.ppt(73页珍藏版)》请在三一办公上搜索。

1、计算机程序设计基础,第五章 程序组织与软件开发方法,提 纲,5.1 库与接口(阅读)5.2 随机数库(阅读)5.3 作用域与生存期(阅读)5.4 宏5.5 条件编译5.6 典型软件开发流程本章小结,5.1 库与接口,库与程序文件程序文件:源文件(*.c)、头文件(*.h)、工程文件库:源文件与头文件接 口通过接口使用库:包括指定库的头文件与源文件优势:不需了解库的实现细节,只需了解库的使用方法,标准 I/O 库,输入输出函数常用函数列表STRING gets(STRING buffer);int printf(CSTRING fmt,);int puts(CSTRING str);int sc

2、anf(CSTRING fmt,);,数学库,数学函数常用函数列表三角函数与反三角函数系列double acos(double x);double sin(double x);幂函数与对数函数系列duoble log(double x);double pow(double x,double y);其他数学函数double sqrt(double x);,标准辅助函数库,工具与辅助函数常用函数列表void exit(int status);void free(void*p);void*malloc(size_t size);int rand();void srand(unsigned int s

3、eed);,头文件的包含策略,包含头文件的格式尖括号:在 C 编译器的标准目录下查找该头文件双引号:首先在当前工程项目所在的目录下查找,若不存在,则查找标准目录使用双引号包含自己或其他编写的非 C 标准库头文件的多次包含多个文件包含同一个头文件例:“zyrandom.h”包含“zylib.h”,“main.c”包含“zyrandom.h”与“zylib.h”,则“main.c”不仅主动包含了“zylib.h”,还通过“zyrandom.h”被动包含了“zylib.h”多次包含同一个头文件可能会导致程序问题,头文件的包含策略,解决方法使用条件编译指令#ifndef(条件判断,若未定义)、#def

4、ine(定义)与#endif(结束条件判断)被包含的头文件#ifndef _ZYLIB_#define _ZYLIB_头文件的具体内容在此#endif源文件或包含文件#ifndef _ZYLIB_#include zylib.h#endif源文件或包含文件的具体内容在此,5.2 随机数库,随机数的生成库的设计原则随机数库接口随机数库实现随机数库测试,随机数的生成第一版,编写程序,调用 rand 函数生成五个随机数,#include#include int main()int i;printf(On this computer,the RAND_MAX is%d.n,RAND_MAX);prin

5、tf(Five numbers the rand function generates as follows:n);for(i=0;i 5;i+)printf(%d;,rand();printf(n);return 0;,随机数的生成第二版,编写程序,调用 rand 函数生成五个随机数,#include#include#include int main()int i;printf(On this computer,the RAND_MAX is%d.n,RAND_MAX);printf(Five numbers the rand function generates as follows:n)

6、;srand(int)time(0);for(i=0;i 5;i+)printf(%d;,rand();printf(n);return 0;,接口设计原则,用途一致接口中所有函数都属于同一类问题操作简单函数调用方便,最大限度隐藏操作细节功能充足满足不同潜在用户的需要性能稳定经过严格测试,不存在程序缺陷,随机数库接口,设计随机数接口,#ifndef _ZYRANDOM_#define _ZYRANDOM_#ifndef _ZYLIB_#include zylib.h#endifvoid Randomize();int GenerateRandomNumber(int low,int high)

7、;double GenerateRandomReal(double low,double high);#endif,随机数库实现,实现随机数库,#include#include#ifndef _ZYRANDOM_#include zyrandom.h#endif#ifndef _ZYLIB_#include zylib.h#endifvoid Randomize()srand(int)time(NULL);,随机数库实现,int GenerateRandomNumber(int low,int high)double _d;if(low high)PrintErrorMessage(FALSE

8、,GenerateRandomNumber:Make sure low high)PrintErrorMessage(FALSE,GenerateRandomReal:Make sure low=high.n);_d=(double)rand()/(double)RAND_MAX+1.0);return(low+_d*(high-low);,随机数库测试,单独测试库的所有函数合法参数时返回结果是否正确非法参数时返回结果是否正确,即容错功能是否正常联合测试多次运行程序,查看生成的数据是否随机测试整数与浮点数随机数是否均能正确工作,5.3 作用域与生存期,量的作用域与可见性量的存储类与生存期函数的

9、作用域与生存期声明与定义,量的作用域与可见性,作用域与可见性作用域:标识符的有效范围可见性:程序中某个位置是否可以使用某个标识符标识符仅在其作用域内可见位于作用域内的标识符不一定可见局部数据对象定义于函数或复合语句块内部的数据对象(包括变量、常量与函数形式参数等)局部数据对象具有块作用域,仅在定义它的块内有效有效性从定义处开始直到该块结束多个函数定义同名的数据对象是允许的,原因?,局部数据对象的作用域,int func(int x,int y)int t;t=x+y;/*单独出现的花括号对用于引入嵌套块*/*允许在块中定义数据对象,作用域仅限本块*/int n=2;printf(n=%d.n,

10、n);return t;,量的作用域与可见性,全局数据对象定义于函数或复合语句块之外的数据对象全局数据对象具有文件(全局)作用域,有效性从定义处开始直到本文件结束,其后函数都可直接使用若包含全局数据对象定义的文件被其他文件包含,则其作用域扩展到宿主文件中,这可能会导致问题,为什么?不要在头文件中定义全局数据对象!函数原型作用域定义在函数原型中的参数具有函数原型作用域,其有效性仅延续到此函数原型结束函数原型中参数名称可以与函数实现中的不同,也可以省略,作用域与可见性示例,1int i;/*全局变量 i 作用域开始,可见*/2int main()34 int n;/*局部变量 n 作用域开始,可见

11、*/5 i=10;/*全局变量 i 有效且可见*/6 printf(i=%2d;n=%2dn,i,n);7 n=func(i);8 printf(i=%2d;n=%2dn,i,n);9/*局部变量 n 作用域结束,不再可见*/10int n;/*全局变量 n 作用域开始,可见*/11int func(int x)/*形式参数 x 作用域开始,可见*/1213 i=0;/*全局变量 i 有效且可见*/14 printf(i=%2d;n=%2dn,i,n);15 n=20;/*全局变量 n 有效且可见*/16/*嵌套块开始*/17 int i=n+x;/*局部变量 i、x 有效可见;全局变量 n

12、有效可见;全局变量 i 有效不可见*/18 printf(i=%2d;n=%2dn,i,n);19/*局部变量 i 作用域结束,全局变量 i 有效且可见*/20 return+i;21/*局部变量 x 作用域结束,不再可见*/22/*文件结束,全局变量 i、n 作用域结束*/,量的存储类与生存期,生存期:量在程序中存在的时间范围C 使用存储类表示生存期作用域表达量的空间特性,存储类表达量的时间特性静态(全局)生存期全局数据对象具有静态(全局)生存期生死仅与程序是否执行有关自动(局部)生存期局部数据对象具有自动(局部)生存期生死仅与程序流程是否位于该块中有关程序每次进入该块时就为该对象分配内存,

13、退出该块时释放内存;两次进入该块时使用的不是同一个数据对象,static 关键字,修饰局部变量:静态局部变量使局部变量具有静态生存期程序退出该块时局部变量仍存在,并且下次进入该块时使用上一次的数据值静态局部变量必须进行初始化不改变量的作用域,仍具有块作用域,即只能在该块中访问,其他代码段不可见修饰全局变量使其作用域仅限定于本文件内部,其他文件不可见,静态局部变量示例,检查下述程序的输出结果,#include int func(int x);int main()int i;for(i=1;i 4;i+)printf(Invoke func%d time(s):Return%d.n,i,func(

14、i);return 0;int func(int x)static int count=0;/*定义静态局部变量count,函数结束后仍存在*/printf(x=%d.n,x);return+count;,函数的作用域与生存期,所有函数具有文件作用域与静态生存期在程序每次执行时都存在,并且可以在函数原型或函数定义之后的任意位置调用内部函数与外部函数外部函数:可以被其他文件中的函数所调用内部函数:不可以被其他文件中的函数所调用函数缺省时均为外部函数内部函数定义:使用 static 关键字内部函数示例:static int Transform(int x);内部函数示例:static int Tr

15、ansform(int x),声明与定义,声明不是定义定义在程序产生一个新实体声明仅仅在程序中引入一个实体函数的声明与定义声明是给出函数原型,定义是给出函数实现代码类型的声明与定义产生新类型就是定义类型定义示例:typedef enum _BOOL FALSE,TRUE BOOL;不产生新类型就不是定义,而仅仅是声明类型声明示例:enum _BOOL;,全局变量的作用域扩展,全局变量的定义不能出现在头文件中,只有其声明才可以出现在头文件中声明格式:使用 extern 关键字/*库的头文件*/*此处仅引入变量 a,其定义位于对应源文件中*/extern int a;/*变量 a 可导出,其他文件

16、可用*/*库的源文件*/*定义变量 a*/int a;,5.4 宏,宏替换含参宏宏与函数的差异宏的特殊用法,宏替换,编译前进行简单文本替换,STRING NAME=The Fundamentals;STRING NAME=The;#defineFALSE0/*宏定义前的标识符不被替换*/#defineTRUE1/*宏定义本身已不再需要*/#defineNAMEQiao Linint main()int main()/*宏定义后标识符全被替换*/STRING MY_NAME=NAME;STRING MY_NAME=Qiao Lin;/*字符串本身不会被替换*/STRING s=NAME;STRI

17、NG s=NAME;if(a=TRUE)if(a=1),宏替换的基本原则,宏定义占用单独一个文本行宏替换时,被替换文字不能是标识符的一部分宏定义中宏名称之后的全部内容都是替换文本,包括该文本行后面的操作符号或标点符号设宏定义:#define ADD a+b;c=ADD 被替换为 c=a+b;可以使用已定义宏定义新宏#define PI 3.14#define AREA PI*r*r;area=AREA;被替换为 area=3.14*r*r;,宏替换的基本原则,宏替换只发生一次,不会嵌套替换#define PI 3.14#define D PI*D*Darea=D;被替换为 area=3.14*

18、D*D;宏定义总是出现在函数声明或定义之外,一般放置在头文件的函数原型开始之前宏定义的有效性从定义处开始直到文件结束如果要提前取消某个宏定义,使用#undef 指令#undef NAME宏的目的:降低改变同样文本时的工作量;为特定文字起个有意义的名称,取代魔数,含参宏,定义格式#define 宏名称(参数列表)替换文本替换时,使用参数列表中的实际参数逐一替换后面宏的替换文本中的形式参数定义与替换示例:看起来像函数#define ADD(x,y)x+yc=ADD(a,b);被替换为 c=a+b;形式参数 x 被实际参数 a 替换,y 被 b 替换含参宏的替换是直接替换#define ADD(x,

19、y)x+yc=ADD(a+b,c);被替换为 c=a+b+c;,含参宏,替换文本中的操作符优先级问题#define PI 3.14#define ADD(x,y)x+y#define AREA(r)PI*r*rc=AREA(ADD(a,b);首先被替换为 c=PI*ADD(a,b)*ADD(a,b);然后被替换为 c=PI*a+b*a+b;解决方案:使用括号#define PI 3.14#define ADD(x,y)(x)+(y)#define AREA(r)(PI*(r)*(r)c=AREA(ADD(a,b);被替换为 c=(PI*(a)+(b)*(a)+(b);,含参宏与函数的异同,函数

20、形式参数与实际参数具有固定类型,并且保持一致;含参宏的参数没有类型要求,甚至可以不是数据对象示例:#define Max(x,y)(x)(y)?(x):(y)可以使用上述宏判断整数或浮点数等类型数据的大小关系,C 语言是不允许为不同数据类型编写同名函数的!函数调用在程序执行时处理,含参宏在编译前处理函数形式参数会在执行时分配存储空间,含参宏的参数不会分配存储空间,不会发生参数传递,也没有返回值函数调用占用程序执行时间,含参宏替换不占用程序执行时间,仅占用编译时间函数调用节省程序代码空间(多次调用使用同样代码),含参宏浪费程序代码空间(多次替换会使得代码膨胀),宏的特殊用法,略感兴趣的可以自学阅

21、读 zylib 库代码需要了解这部分内容,5.5 条件编译,略基础知识:见头文件的包含策略复杂内容:感兴趣的可以自学,开发大型程序才需要了解,5.6 典型软件开发流程,软件工程概要问题的提出需求分析概要设计详细设计编码实现系统测试经验总结,软件工程概要,需求分析:确定软件需要解决什么问题决定因素:人软件开发人员需要与用户深入交流,明确问题的输入、输出以及其他附加信息不要轻视任何问题!方案设计:设计程序框架概要设计:设计总体方案,形成高层模块划分详细设计:细化模块,获得各模块的输入、输出与算法编码实现:实际编程系统测试:测试程序的正确性与稳定性经验总结,软件开发流程图,软件开发问题,我猜!我猜!

22、我猜猜猜!编程实现一个简单的猜价格游戏假设有某物品,已知其最低价格与最高价格游戏参与者在给定次数内猜测其价格具体值若游戏者成功猜出其价格,作为奖励将得到该物品,需求分析,需求A:游戏运行前首先应向游戏参与者介绍游戏功能需求B:首期工程不需要解决游戏难度问题,用户迫切希望程序能在最短时间内运行起来,因此只考虑最简单情形需求C:在每个游戏回合结束时允许用户选择是否重新开始新游戏,这里游戏回合是指游戏参与者或者猜中价格或者其猜测机会已用完,如果用户没有选择退出,游戏应无休止地玩下去需求D:能够记录游戏参与者的游戏信息,目前仅统计用户玩了多少回合以及赢了多少回合需求E:在用户退出游戏时,给出此次游戏胜

23、率,需求分析,不明确的地方:什么是最简单情形?与用户再次沟通需求B1:设物品最低价格为100元,最高价格为200元需求B2:物品实际价格由系统运行时随机生成需求B3:游戏参与者最多允许猜6次需求B4:若游戏参与者猜测价格比实际价格高,则程序提示“高”;若猜测价格比实际价格低,提示“低”用户补充需求需求F:需要定义游戏初始化过程,未来有可能通过它调整游戏难度,程序必须为此提供接口,概要设计,响应需求 A、E、F将游戏划分为四个模块:欢迎信息显示模块、游戏初始化模块、游戏模块、游戏结束模块程序架构:主文件“main.c”,程序主体函数库“guess.h”与“guess.c”;此外需要使用 zyli

24、b 与 zyrandom 库设计函数原型胜率信息需要从游戏模块传递给游戏结束模块void PrintWelcomeInfo();void InitializeGame();double PlayGame();void PrintGameOverInfo(double prevailed_ratio);,guess.h,#ifndef _EG0507GUESS_#define _EG0507GUESS_void PrintWelcomeInfo();void InitializeGame();double PlayGame();void PrintGameOverInfo(double prev

25、ailed_ratio);#endif,main.c,#ifndef _EG0507GUESS_#include guess.h#endifint main()double prevailed_ratio;PrintWelcomeInfo();InitializeGame();prevailed_ratio=PlayGame();PrintGameOverInfo(prevailed_ratio);return 0;,概要设计,响应需求 C使用无限循环作为游戏模块的主架构:初始化游戏回合,进行游戏回合,判断游戏参与者是否开始新游戏回合响应需求 B2每一回合需要随机生成物品价格,应在游戏回合初始

26、化阶段完成抽象出单独的游戏回合初始化函数,返回值为初始化的物品价格(整数类型)int InitializeBout();响应需求 D游戏参与者的回合数与获胜回合数:使用整数类型保存,游戏开始时初始化为 0,并随着游戏进程变化,概要设计,游戏回合活动分析将每一回合游戏抽象成函数,函数返回值为 BOOL,表示该游戏回合游戏参与者是否获胜BOOL PlayBout();判断用户是否进入下一回合BOOL Again();Again函数负责在 PlayGame 函数中充当哨兵,在返回值为 FALSE 时退出游戏响应需求 B1、B3:数据初始化工作const int lowest_price=100;co

27、nst int highest_price=200;const int guesstimate_count=6;,详细设计,响应需求 B4:细化 PlayBout在给定猜测次数内接受游戏参与者的输入价格,判断与实际价格是否相同,如果不同则给出提示信息,如果相同则恭喜游戏参与者获胜但是需求 G:一旦游戏参与者给出了猜测价格,当该价格或高或低时,提示游戏参与者的信息应能够相应缩小价格区间以反映此变化响应需求 G:修改 PlayBout 函数,添加参数BOOL PlayBout(int actual_price,int lower_price,int higher_price,int chances

28、_left);,详细设计,欢迎信息模块设计要求:将游戏性质与游戏方法告诉游戏参与者,系统应尽可能输出详细信息,例如物品最低价格、最高价格与猜测次数都应通知游戏参与者伪代码,void PrintWelcomeInfo()输出程序性质信息 物品最低价格、最高价格与猜测次数一并输出,详细设计,游戏初始化模块设计要求:不知道伪代码,void InitializeGame(),详细设计,游戏结束模块设计要求:如果能够在游戏结束模块不仅输出游戏参与者胜率,还针对其胜率高低输出不同鼓励信息就好了需求 H:当游戏参与者胜率超过75%(含)时,输出“You luckyyyyyyyyyyyyy!”;当胜率低于75

29、%但超过50%(含)时,输出“So gooooooood.”;其他输出“You can do it better.Wish you luck.”伪代码,void PrintGameOverInfo(double prevailed_ratio)输出百分制胜率 根据胜率分别输出不同信息,详细设计,游戏模块细化伪代码,double PlayGame()while(TRUE)调用 InitializeBout 获得实际价格 调用 PlayBout 启动游戏回合 如果游戏回合结束后结果为 TRUE,递增获胜回合数 递增总回合数 调用 Again,若结果为 FALSE,终止游戏,否则继续 返回最终胜率,

30、详细设计,游戏回合初始化与游戏初始化模块细化伪代码,int InitializeBout()调用 GenerateRandomNumber 函数 并返回其结果void InitializeGame()调用 Randomize 函数启动随机数发生器,详细设计,游戏回合模块细化需求 I:如果游戏参与者给出的猜测价格不在当时价格范围内,应提醒用户重新提供新价格,此次操作不应递减用户猜测次数,以防止用户输入错误,也就是说,需要检查猜测价格的合法性需求 J:当最后一次机会也未猜中价格时,不需要再输出提示价格高低信息,直接输出用户本回合失败信息,并将实际价格告诉用户,详细设计,BOOL PlayBout(

31、int actual_price,int lower_price,int higher_price,int chances_left)while(还有猜测机会)获得游戏参与者猜测价格,检查游戏参与者猜测价格是否在给定范围 递减游戏参与者猜测机会 判断猜测价格高低 switch(判断结果)case 高了:if(还有猜测机会)输出价格高了信息,降低最高价格值,缩小猜测区间 else 输出失败信息与物品实际价格,结束函数,返回本回合失败值 FALSE break;case 低了:if(还有猜测机会)输出价格低了信息,增大最低价格值,缩小猜测区间 else 输出失败信息与物品实际价格,结束函数,返回本

32、回合失败值 FALSE break;default:输出游戏参与者获胜信息,结束函数,返回 TRUE 程序流程至此,说明游戏参与者本回合已失败,返回 FALSE,详细设计,进一步细化游戏回合函数抽象三个辅助函数获得游戏参与者猜测价格:int GetGuesstimatePrice(int lower_price,int higher_price,int chances_left);检查游戏参与者猜测价格是否在给定范围:int CheckValidationOfGuesstimatePrice(int lower_price,int higher_price,int guesstimate_pr

33、ice);判断猜测价格高低:int JudgeGuesstimatePrice(int actual_price,int guesstimate_price);,详细设计,int GetGuesstimatePrice(int lower_price,int higher_price,int chances_left)输出提示信息,包括最低价格,最高价格与剩余猜测次数 调用 GetIntegerFromKeyboard 获取猜测价格并返回int CheckValidationOfGuesstimatePrice(int lower_price,int higher_price,int gues

34、stimate_price)while(猜测价格小于最低价格或高于最高价格)通知游戏参与者猜测价格超出范围,提醒用户重新输入新价格 调用 GetIntegerFromKeyboard 获取新猜测价格 返回新猜测价格int JudgeGuesstimatePrice(int actual_price,int guesstimate_price)获得猜测价格与实际价格之差 if(差值大于0)return 1;else if(差值小于0)return-1;else return 0;,详细设计,细化 Again 函数Zylib 库的字符串比较函数BOOL IsStringEqual(STRING s

35、1,STRING s2)BOOL IsStringEqualWithoutCase(STRING s1,STRING s2)伪代码,BOOL Again()询问游戏参与者是否开始新游戏 获取游戏参与者的响应 调用!IsStringEqualWithoutCase 函数,判断游戏参与者的响应是否为“n”如果真,返回 FALSE,即将上述返回值取反返回,详细设计,编码实现,#include#ifndef _ZYLIB_#include zylib.h#endif#ifndef _ZYRANDOM_#include zyrandom.h#endif#ifndef _EG0507GUESS_#incl

36、ude guess.h#endifconst int lowest_price=100;const int highest_price=200;const int guesstimate_count=6;,编码实现,static int InitializeBout();static BOOL PlayBout(int actual_price,int lower_price,int higher_price,int chances_left);static BOOL Again();static int GetGuesstimatePrice(int lower_price,int high

37、er_price,int chances_left);static int CheckValidationOfGuesstimatePrice(int lower_price,int higher_price,int guesstimate_price);static int JudgeGuesstimatePrice(int actual_price,int guesstimate_price);,编码实现,void PrintWelcomeInfo()printf(The program lists a product with price between%d and%d(RMB Yuan

38、).n,lowest_price,highest_price);printf(You give a guesstimate price.If the price you give is correct,you win.n);printf(You have%d chances.n,guesstimate_count);printf(Rise to the challenge to win your bonus.n);void InitializeGame()int i,n;Randomize();,编码实现,double PlayGame()int actual_price,lower_pric

39、e=lowest_price,higher_price=highest_price;int chances_left=guesstimate_count;int bout_count=0,prevailed_bout_count=0;while(TRUE)printf(n);actual_price=InitializeBout();if(PlayBout(actual_price,lower_price,higher_price,chances_left)prevailed_bout_count+;bout_count+;if(!Again()break;return(double)prev

40、ailed_bout_count/(double)bout_count;,编码实现,void PrintGameOverInfo(double prevailed_ratio)printf(nprevailed ratio:%.2lf%.n,prevailed_ratio*100);if(prevailed_ratio=0.75)printf(You luckyyyyyyyyyyyyy!nn);else if(prevailed_ratio=0.50)printf(So gooooooood.nn);else printf(You can do it better.Wish you luck.

41、nn);static int InitializeBout()return GenerateRandomNumber(lowest_price,highest_price);,编码实现,static BOOL PlayBout(int actual_price,int lower_price,int higher_price,int chances_left)int guesstimate_price;int judge_result;while(chances_left 0)guesstimate_price=GetGuesstimatePrice(lower_price,higher_pr

42、ice,chances_left);guesstimate_price=CheckValidationOfGuesstimatePrice(lower_price,higher_price,guesstimate_price);chances_left-;judge_result=JudgeGuesstimatePrice(actual_price,guesstimate_price);switch(judge_result)case 1:if(chances_left 0)printf(nHigher.n);higher_price=guesstimate_price-1;else prin

43、tf(nYou lose this bout.The actual price is%d.n,actual_price);return FALSE;break;case-1:if(chances_left 0)printf(nLower.n);lower_price=guesstimate_price+1;else printf(nYou lose this bout.The actual price is%d.n,actual_price);return FALSE;break;default:printf(nYou winnnnnnnnnnnnnnnn!n);return TRUE;ret

44、urn FALSE;,编码实现,static BOOL Again()printf(nPlay a new game(n to stop,other words to play again)?);return!IsStringEqualWithoutCase(GetStringFromKeyboard(),n);static int GetGuesstimatePrice(int lower_price,int higher_price,int chances_left)printf(The actual price is at%d,%d.,lower_price,higher_price);

45、printf(Chances left%d.nYou guess:,chances_left);return GetIntegerFromKeyboard();,编码实现,static int CheckValidationOfGuesstimatePrice(int lower_price,int higher_price,int guesstimate_price)int t=guesstimate_price;while(t higher_price)printf(Guesstimate price%d is out of the range.,t);printf(Please choo

46、se one in%d,%d.nTry again:,lower_price,higher_price);t=GetIntegerFromKeyboard();return t;static int JudgeGuesstimatePrice(int actual_price,int guesstimate_price)int t=guesstimate_price-actual_price;if(t 0)return 1;else if(t 0)return-1;else return 0;,系统测试,所有数据对象是否已正确初始化?随机生成的价格是否合理有效?测试过程可能需要在源程序中添加必

47、要的测试代码,例如:double PlayGame()actual_price=InitializeBout();#ifndef NDEBUG printf(Debugging PlayGame:Actual price=%d.n,actual_price);#endif,系统测试,检查游戏回合运行是否准确参数传递是否准确?获取的猜测价格是否与游戏参与者的实际输入吻合?价格有效性检查是否正确工作?分别输入准确值、高于最高价格值与低于最低价格值,查看程序运行结果价格判断是否正确运行?猜测次数的控制与显示是否准确反映了用户猜测过程的变化?提示信息是否准确显示?在显示未猜中信息时,是否最后一次与其他

48、次不同?,系统测试,判断开始新游戏的过程是否准确是否在游戏参与者输入了“n”后退出?是否即使输入了“no”,游戏也仍然运行?检查胜率计算是否准确检查胜率百分比的计算与显示是否准确不同鼓励语是否显示准确测试必须覆盖三类可能胜率测试人员试玩游戏,得到三种不同胜率结果,经验总结,Q:这个问题一开始大家认为它难不难?A:不难。Q:程序设计难不难?A:难,如果要程序员从系统分析、方案设计开始做起的话。Q:编码难不难?A:不难,与系统分析与设计相比编码实在简单,不过就是使用了所有代码控制结构和函数编写原则而已。Q:和用户交流烦不烦?A:烦!,本章小结,程序组织结构多文件工程项目的组织、头文件的包含策略、作用域与生存期、static 与 extern 关键字、宏、条件编译库与接口的基本概念与设计原则、设计方法库:将复杂代码按照逻辑和功能进行分组以相互独立开来库与用户之间只能通过接口进行通讯库设计原则:用途一致、操作简单、功能充足、性能稳定程序设计与软件工程的关系自顶向下、逐步求精需求分析、概要设计、详细实现、编码实现和系统测试什么是程序员最重要的品格?不是聪明睿智,更不是团结协作,而是耐心,耐心,再耐心,作 业,第 198 页:习题二第 1、2小题第 3 小题选做,

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

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号