设计阶段
自顶向下的分解,每个小问题设计为一个函数,公共小问题可以设计成一个库
类型定义格式
enum 枚举类型名 {元素表};
石头、剪子、布中的枚举类型
enum studentNum{1001, 1002, 1003, 1004}
是不合法的枚举常量,因为大括号{}中是一个用逗号分隔的标识符列表。标识符由字母(A-Z,a-z)、数字(0-9)、下划线“_”组成,并且首字符不能是数字。
#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 namespace std;
enum p_r_s
{
paper,
rock,
scissor,
game,
help,
quit
};
enum outcome
{
win,
lose,
tie
};
outcome compare(p_r_s player_choice, p_r_s machine_choice);
void prn_game_status();
void prn_help();
void report(outcome result);
p_r_s selection_by_machine();
p_r_s selection_by_player();
#endif
cpp
文件内include
自定义的头文件,例如myMath.h
,则代码是:#include "myMath.h"
cpp
实现代码混入头文件中,来简化代码编写,c++程序的头文件后缀名是.hpp
int
型变量x
,需要在代码int x
;之前添加 extern
关键字,并在.cpp
文件中定义int x;
主模块的实现
// 文件:main.cpp
// 石头、剪子、布游戏的主模块
#include "p_r_s.h"
int main()
{
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_machine();
result = compare(player_choice, machine_choice);
report(result);
break;
case game:
prn_game_status();
break;
case help:
prn_help();
}
prn_game_status();
return 0;
}
Select模块的实现
//文件:select.cpp
//包括机器选择selection_by_machine和玩家选择selection_by_player函数的实现
#include "p_r_s.h"
p_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 << "please select: ";
cin >> c;
switch (c)
{
case 'p':
player_choice = paper;
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函数的实现
#include "p_r_s.h"
outcome 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 == paper) ? win : lose;
}
return result;
}
Print模块的实现
//文件:print.cpp
//包括所有与输出有关的模块。
//有prn_game_status,prn_help和report函数
#include "p_r_s.h“
static int win_cnt = 0, lose_cnt = 0, tie_cnt = 0; //模块的内部状态
void report(outcome result)
{
switch (result)
{
case win:
++win_cnt;
cout << "You win. \n";
break;
case lose:
++lose_cnt;
cout << "You lose.\n";
break;
case tie:
++tie_cnt;
cout << "A tie.\n";
break;
}
}
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 prn_help()
{
cout << endl
<< "The following characters can be used:\n"
<< " p for paper\n"
<< " r for rock\n"
<< " s for scissors\n"
<< " g print the game status\n"
<< " h help, print this list\n"
<< " q quit the game\n";
}
库的概念
库的设计和实现
1.库功能
int RandomInteger(int low, int high)
RandomInit()
实现设置随机数种子的功能2.接口文件
#ifndef _name_h
#define _name_h
头文件真正需要写的内容
#endif
3.随机函数库接口文件
//文件:Random.h
//随机函数库的头文件
#ifndef _random_h
#define _random_h
//函数:RandomInit
//用法:RandomInit()
//作用:此函数初始化随机数种子
void RandomInit();
//函数:RandomInteger
//用法:n = RandomInteger(low, high)
//作用:此函数返回一个 low 到 high 之间的随机数,包括 low 和 high
int RandomInteger(int low, int high);
#endif
4.库的实现
include
此cpp
文件所需的头文件5.随机函数库实现文件
//文件: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 + i
int RandomInteger(int low, int high)
{
return (low + (high - low + 1) * rand() / (RAND_MAX + 1));
}
6.统计学函数库接口文件
//文件:statistics.h
//统计学函数库
#ifndef _statistics_h
#define _statistics_h
//函数:Average
//用法:double ave = Average(double*, double*)
//作用:计算从数组中所有实数的算数平均值
double Average(double *begin, double *end);
//函数:MinMax
//用法:MinMax(double *, double *, double &, double &)
//作用:统计数组的最小最大值,并且通过引用传参得到结果
void MinMax(double *begin, double *end, double &Min, double &Max);
//函数:Median
//用法:double med = Median(double*, double*)
//作用:计算从数组中所有实数的中位数
double Median(double *begin, double *end);
//函数:Mode
//用法:double mod = Mode(double*, double*)
//作用:计算从数组中所有实数的众数
double Mode(double *begin, double *end);
#endif
将龟兔赛跑的模拟问题划分成主模块、移动模块、输出模块分别处理,是运用了自顶向下分解的设计思路。
使用程序员自己定义的库函数的时候,需要在使用之前include
本地头文件.h
文件,并且编译时需要将主程序与库函数的实现文件.cpp
文件链接起来
主模块
#include "Random.h" //包含随机数库
#include
using namespace std;
const int RACE_END = 70; //设置跑道的长度
int move_tortoise();
int move_hare();
void print_position(int, int, int);
int main()
{
int hare = 0, tortoise = 0, timer = 0;
RandomInit(); //随机数初始化
cout << "timer tortoise hare\n"; //输出表头
while (hare < RACE_END && tortoise < RACE_END)
{
tortoise += move_tortoise(); //乌龟移动
hare += move_hare(); //兔子移动
print_position(timer, tortoise, hare);
++timer;
}
if (hare > tortoise)
cout << "\n hare wins!\n";
else
cout << "\n tortoise wins!\n";
return 0;
}
移动模块
// 文件名: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; //睡觉
else 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) //每隔6秒空一行
cout << endl;
cout << timer << '\t' << t << '\t' << h << '\n';
}