当前课程知识点:基于Linux的C++ >  第五讲 程序组织与开发方法 >  5.7 典型软件开发流程(二) >  LinuxCPP0507

返回《基于Linux的C++》慕课在线视频课程列表

LinuxCPP0507在线视频

LinuxCPP0507

下一节:LinuxCPP0508

返回《基于Linux的C++》慕课在线视频列表

LinuxCPP0507课程教案、知识点、字幕

接下来就是详细设计

然后细化PlayBout

在给定的猜测次数内

接受游戏参与者输入的价格

然后判断和实际价格是不是一样的

如果不一样就得提示他

高了就是说高了 低了就是说低了

如果是一样的 你赢了

真实的程序开发的时候

要跟客户讨论

你想让我给你写什么程序

你的程序需要完成什么功能

客户不一定一开始就能把这个讲全了

他能够想清楚就不容易了

再清楚地表达出来是非常非常难的

所以很多时候

他其实不知道应该怎么跟你说

他希望程序能解决什么东西

具有什么样的功能、

概要设计、详细设计

都给他看了

反而能够给他提示

想起来了 有一个需求G 刚才忘了说

一旦游戏参与者给出了猜测的价格

如果价格高了或者低了

提示用户的时候

猜测的价格区间就应该反映这个变化

原始价格在100到200之间

然后玩家来猜

150 高了

接下来你给用户提示的时候

价格区间在100到149之间

需要响应区间的变化

就意味着PlayBout函数

需要接受最重要的几个参数

第一 实际价格是多少

第二个 较低的价格是多少

第三个 较高的价格是多少

第四个 还有几次猜测机会

区间是不断变化的

函数接口就做了修正

接下来就是PrintWelcomeInfo

提示欢迎信息的

告诉玩家这个程序该怎么玩

所有细节信息就在这里面输出

再接下来就是游戏的初始化模块

InitializeGame

就把函数框架写上就行了

函数头部花括号里面什么也没填

然后继续

游戏结束模块要输出胜率

然后客户一拍脑袋:“我刚才又忘了说!”

忘了你就得补

需求H:当游戏参与者的胜率

超过75%的时候

输出“You luckyyyyyyyyyyyyy!”

如果当胜率低于75%但超过50%的时候

“So gooooooood!”.

其它的情况

就是胜率不到一半

输出“You can do it better. Wish you luck.”

你千万不要说“You stupid!”

这个不成 给点鼓励语

我们就根据不同的胜率

输出不同的提示信息

这就是我们新的需求H

编程其实很简单 一个if-else if-else

其实就搞定了

继续游戏模块 这才是重头戏

PlayGame

While(true)无限循环

调用InitializeBout

初始化这个游戏回合

生成物品的实际价格

然后PlayBout开始玩这个游戏

游戏结束了

如果返回值是true 说明玩家赢了

递增他获胜的回合数

否则的话就不递增了

不管怎么样 要递增总回合数

然后调用Again 问你是不是继续玩

如果是true就继续

如果是false 就break终止我们的游戏

返回它最终的胜率

这个就是PlayGame函数的伪代码

逻辑上是相当清晰的

现在回到InitializeBout这个函数

就是游戏回合的初始化

在100到200之间

生成物品的实际价值

调用GenerateRandomNumber

来生成这样随机数

用它来作为物品的实际价格

你一下就想起来了

既然我要调用GenerateRandomNumber

来生成一个随机的整数

那么一定需要Randomize一次函数调用

这个随机化动作在哪里做呢

显然不能够在InitializeBout里面做

干脆放在InitializeGame这个函数里

这个是非常重要的设计

就为InitializeGame找了一个事情做

继续详细设计

游戏模块还要细化呢

你的客户又一拍脑袋

又来俩新需求 需求I

如果游戏参与者给出了猜测价格

不在当前区间里

你比如说原来实际价格就100到200之间

然后他一下子敲错键盘了 给你250

因为已经很明确地说了

这个物品价格在100到200之间

给我250这个数字没有意义

如果我算这个数据是有效的

机会就浪费了

正常情况下

游戏应该把这个机会给扣掉

不算他浪费了一次机会

就是说你这个数据是非法的

有效的数字才认为

你用了一次猜测机会

然后是需求J

当最后一次猜测机会在101和102之间

最后没猜对

那用户其实立即就能够知道

它实际价格是什么

可是如果他很不幸

数据在140到150之间

实际上还有11个数让他猜

最后就一次机会了

他也没猜对

这个概率就低了

他没猜对 程序就说你失败了 结束了

玩家抓耳挠腮的

实际数是多少啊 你得跟我说呀

你怎么最后不跟我说实际数是多少

当他猜测机会用完了也没猜对

别跟我说高了、低了

直接告诉他实际价格是多少

别再瞒着他了

PlayBout伪代码

看上去很复杂 代码很多的样子

其实就是对我们原来那个伪代码

做了一次更细化的动作

整体代码本身并没有特别复杂

就是while循环 里面一个switch

几个函数调用

进一步细化有序回合的话

你会发现这里边

其实还需要使用到三个辅助的函数

第一个需要从终端

接受用户输入猜测的价格

这个函数叫GetPrice

第二个我得判断用户猜测的价格

是不是在给定的合法有效的区间里

叫CheckPrice

第三个还要判断用户的价格

和实际价格 高了、低了大小关系

这个我们有一个JudgePrice函数

就是为PlayBout所实现的附加函数

具体的函数的伪代码都在这里

还有一个Again

Again这个函数就要询问玩家

游戏还要不要玩

接受用户的输入

要继续玩 就继续玩

不玩了 Again就返回false

这个是again函数的伪代码

现在呢 就画一个图

把这些实现的函数

和它们之间调用的关系画出来

别说同学们想象不到

这里面定义了那么多函数

就我为了这门课程举这个例子的时候

我其实都没有想到这个程序

最终会实现这么多个函数

从足球的角度来讲

这叫433阵形

连同main正好11个

main函数需要使用到4个函数

PrintWelcomeInfo、InitializeGame、

PlayGame、PrintgameOverInfo

然后PlayGame要使用到

InitializeBout、PlayBout、Again这三个函数

PlayBout要使用GetPrice、

CheckPrice、JudgePrice这三个函数

这个就是整个程序

实现出来以后的框架

现在你看到整个程序逻辑

是非常非常清晰的

实现了11个函数 对于这道题

你想象一下

一开始的时候没觉得这个题

有多么复杂

但是最终写出的代码

居然包括了11个函数

这样的话 程序组织当然就会很清晰

接下来就是guess这个库的具体实现

“guess.cpp”

具体的代码就不解释了

感兴趣的同学

回去可以照着我的片子

把这个代码敲进去 运行一下

体会一下这个程序是怎么实现的

最后要对整个程序进行系统测试

这个系统测试其实非常复杂

比如说这里面数据对象

是不是都弄对了

随机生成的价格是不是合理

猜测的过程、取用户输入数据的过程

有没有问题

所有这些信息其实都需要进行测试

自己就先玩两遍吧

玩两遍的时候要生成价格

然后你真地就自己在那个地方瞎蒙吗

你也不知道它生成的实际价格是多少吗

那个测试的话 效率就太低了

所以真实测试的时候

可能说干脆就直接输出实际的价格

那么在真实程序运行的时候

这一段输出肯定是不能要的

你还能把实际价格输出以后让他猜

那还猜什么呀

所以这个程序真正发布的时候

这行代码一定是要删掉的

可是如果总是一开始测试的时候贴上去

后来又删除

那当代码量很大的时候很难删的

一不小心就删错了

在这种情况下就有一个小技巧

凡是用于测试的这些输出

在未来都不应该出现

用一个宏给包出来

#ifndef NDEBUG、#endif

#ifndef是什么呢

就是如果没有定义

后面跟着那个宏的名字 NDEBUG

那么编译器 就编译cout这条语句

结束这个宏的测试

如果你定义那个宏

那么它里面封包的

cout这条语句就不编译了

所以就不需要你删除

想去掉这样cout的语句 很简单

在程序的最开头写上一行

#define NDEBUG

所有的在#ifndef NDEBUG、#endif中间的这些代码

全部会跳过 不再编译

这是系统测试的小技巧

还有呢 系统测试还没完

游戏的回合还要检查它是不是对

包括参数传递对不对

获取猜测的价格

最低价、最高价的价格判断

猜测次数、提示信息的显示

你都需要测试的

要有一个完整的系统测试的计划

一条一条地去对照

看你的程序运行得对不对

真把这个东西测试完

它的工作量其实是巨大的

这个程序到现在算写完了

对它做一个经验的总结

这个问题一开始大家觉得它难不难

刚开始看到这个题目的时候

你不会觉得它很难

整个程序做设计难不难

如果让你从需求分析、方案设计、

编码实现、系统测试

从头到尾全部走一遍的话

这个程序其实就是蛮难的

一天、两天你都搞不定

那你真要说编码难不难呢

还真的一点都不难

如果我有了一个详细的方案

算法都写在那个地方

剩下无非是用C/C++的代码

把它填充进去就完了

就用了if、switch、for、while

几个函数调用

就实现了这些东西

你别看代码量不短

但它实际上非常非常简单

编码本身并不难

最后你会发现

你和用户交流烦不烦 烦

大部分用户让你给他写程序

他说不清楚他需要啥

所以你要不断跟他交流

不断跟他进行沟通

写方案、做方案给他看

讨论 然后再反馈 让你修改

这个过程是个不断反复的过程

你要没有很高的情商

能够和他做顺畅的交流

那么系统需求你就分析不出来

基于Linux的C++课程列表:

第一讲 C/C++基本语法元素

-1.1 提纲

--LinuxCPP0101

-1.2 程序设计的基本概念

--LinuxCPP0102

-1.3 简单C/C++程序介绍

--LinuxCPP0103

-1.4 程序设计的基本流程

--LinuxCPP0104

-1.5 基本语法元素

--LinuxCPP0105

-1.6 程序设计风格

--LinuxCPP0106

-1.7 编程实践

--LinuxCPP0107

-第一讲 C/C++基本语法元素--编程实践提交入口

第二讲 程序控制结构

-2.1 提纲

--LinuxCPP0201

-2.2 结构化程序设计基础

--LinuxCPP0202

-2.3 布尔数据

--LinuxCPP0203

-2.4 分支结构

--LinuxCPP0204

-2.5 break语句

--LinuxCPP0205

-2.6 循环结构

--LinuxCPP0206

-2.7 编程实践

--LinuxCPP0207

-第二讲 程序控制结构--编程实践提交入口

第三讲 函数

-3.1 提纲

--LinuxCPP0301

-3.2 函数声明、调用与定义

--LinuxCPP0302

-3.3 函数调用栈框架

--LinuxCPP0303

-3.4 编程实践

--LinuxCPP0304

-第三讲 函数--编程实践提交入口

第四讲 算法

-4.1 提纲

--LinuxCPP0401

-4.2 算法概念与特征

--LinuxCPP0402

-4.3 算法描述

--LinuxCPP0403

-4.4 算法设计与实现

--LinuxCPP0404

-4.5 递归算法(一)

--LinuxCPP0405

-4.6 递归算法(二)

--LinuxCPP0406

-4.7 容错与计算复杂度

--LinuxCPP0407

-4.8 编程实践

--LinuxCPP0408

-第四讲 算法--编程实践提交入口

第五讲 程序组织与开发方法

-5.1 提纲

--LinuxCPP0501

-5.2 库与接口

--LinuxCPP0502

-5.3 随机数库(一)

--LinuxCPP0503

-5.4 随机数库(二)

--LinuxCPP0504

-5.5 作用域与生存期

--LinuxCPP0505

-5.6 典型软件开发流程(一)

--LinuxCPP0506

-5.7 典型软件开发流程(二)

--LinuxCPP0507

-5.8 编程实践

--LinuxCPP0508

-第五讲 程序组织与开发方法--编程实践提交入口

第六讲 复合数据类型

-6.1 提纲

--LinuxCPP0601

-6.2 字符

--LinuxCPP0602

-6.3 数组(一)

--LinuxCPP0603

-6.4 数组(二)

--LinuxCPP0604

-6.5 结构体

--LinuxCPP0605

-6.6 编程实践

--LinuxCPP0606

-第六讲 复合数据类型--编程实践提交入口

第七讲 指针与引用

-7.1 提纲

--LinuxCPP0701

-7.2 指针基本概念

--LinuxCPP0702

-7.3 指针与函数

--LinuxCPP0703

-7.4 指针与复合数据类型(一)

--LinuxCPP0704

-7.5 指针与复合数据类型(二)

--LinuxCPP0705

-7.6 字符串

--LinuxCPP0706

-7.7 动态存储管理(一)

--LinuxCPP0707

-7.8 动态存储管理(二)

--LinuxCPP0708

-7.9 引用

--LinuxCPP0709

-7.10 编程实践

--LinuxCPP0710

-第七讲 指针与引用--编程实践提交入口

第八讲 链表与程序抽象

-8.1 提纲

--LinuxCPP0801

-8.2 数据抽象(一)

--LinuxCPP0802

-8.3 数据抽象(二)

--LinuxCPP0803

-8.4 链表(一)

--LinuxCPP0804

-8.5 链表(二)

--LinuxCPP0805

-8.6 链表(三)

--LinuxCPP0806

-8.7 链表(四)

--LinuxCPP0807

-8.8 函数指针(一)

--LinuxCPP0808

-8.9 函数指针(二)

--LinuxCPP0809

-8.10 抽象链表(一)

--LinuxCPP0810

-8.11 抽象链表(二)

--LinuxCPP0811

-8.12 编程实践

--LinuxCPP0812

-第八讲 链表与程序抽象--编程实践提交入口

第九讲 类与对象

-9.1 提纲

--LinuxCPP0901

-9.2 程序抽象与面向对象

--LinuxCPP0902

-9.3 类类型

--LinuxCPP0903

-9.4 对象(一)

--LinuxCPP0904

-9.5 对象(二)

--LinuxCPP0905

-9.6 类与对象的成员(一)

--LinuxCPP0906

-9.7 类与对象的成员(二)

--LinuxCPP0907

-9.8 类与对象的成员(三)

--LinuxCPP0908

-9.9 继承(一)

--LinuxCPP0909

-9.10 继承(二)

--LinuxCPP0910

-9.11 继承(三)

--LinuxCPP0911

-9.12 多态(一)

--LinuxCPP0912

-9.13 多态(二)

--LinuxCPP0913

-9.14 编程实践

--LinuxCPP0914

-第九讲 类与对象--编程实践提交入口

第十讲 操作符重载

-10.1 提纲

--LinuxCPP1001

-10.2 四则运算符重载(一)

--LinuxCPP1002

-10.3 四则运算符重载(二)

--LinuxCPP1003

-10.4 关系与下标操作符重载

--LinuxCPP1004

-10.5 赋值操作符重载(一)

--LinuxCPP1005

-10.6 赋值操作符重载(二)

--LinuxCPP1006

-10.7 赋值操作符重载(三)

--LinuxCPP1007

-10.8 赋值操作符重载(四)

--LinuxCPP1008

-10.9 赋值操作符重载(五)

--LinuxCPP1009

-10.10 流操作符重载(一)

--LinuxCPP1010

-10.11 流操作符重载(二)

--LinuxCPP1011

-10.12 流操作符重载(三)

--LinuxCPP1012

-10.13 操作符重载总结

--LinuxCPP1013

-10.14 编程实践

--LinuxCPP1014

-第十讲 操作符重载--编程实践提交入口

第十一讲 泛型编程

-11.1 提纲

--LinuxCPP1101

-11.2 泛型编程概览

--LinuxCPP1102

-11.3 异常处理机制(一)

--LinuxCPP1103

-11.4 异常处理机制(二)

--LinuxCPP1104

-11.5 运行期型式信息(一)

--LinuxCPP1105

-11.6 运行期型式信息(二)

--LinuxCPP1106

-11.7 模板与型式参数化

--LinuxCPP1107

-11.8 题外话:术语翻译

--LinuxCPP1108

-11.9 泛型编程实践(一)

--LinuxCPP1109

-11.10 泛型编程实践(二)

--LinuxCPP1110

-11.11 泛型编程实践(三)

--LinuxCPP1111

-11.12 泛型编程实践(四)

--LinuxCPP1112

-11.13 泛型编程实践(五)

--LinuxCPP1113

-11.14 泛型编程实践(六)

--LinuxCPP1114

-11.15 泛型编程实践(七)

--LinuxCPP1115

-11.16 泛型编程实践(八)

--LinuxCPP1116

-11.17 泛型编程实践(九)

--LinuxCPP1117

-11.18 泛型编程实践(十)

--LinuxCPP1118

-11.19 编程实践

--LinuxCPP1119

-第十一讲 泛型编程--编程实践提交入口

第十二讲 Linux系统编程基础

-12.1 提纲

--LinuxCPP1201

-12.2 程序执行环境(一)

--LinuxCPP1202

-12.3 程序执行环境(二)

--LinuxCPP1203

-12.4 程序执行环境(三)

--LinuxCPP1204

-12.5 程序执行环境(四)

--LinuxCPP1205

-12.6 输入输出(一)

--LinuxCPP1206

-12.7 输入输出(二)

--LinuxCPP1207

-12.8 文件系统

--LinuxCPP1208

-12.9 设备

--LinuxCPP1209

-12.10 库(一)

--LinuxCPP1210

-12.11 库(二)

--LinuxCPP1211

-12.12 makefile文件(一)

--LinuxCPP1212

-12.13 makefile文件(二)

--LinuxCPP1213

-12.14 makefile文件(三)

--LinuxCPP1214

-12.15 编程实践

--LinuxCPP1215

-第十二讲 Linux系统编程基础--编程实践提交入口

第十三讲 进程编程

-13.01 提纲

--LinuxCPP1301

-13.02 进程基本概念

--LinuxCPP1302

-13.03 信号

--LinuxCPP1303

-13.04 进程管理(一)

--LinuxCPP1304

-13.05 进程管理(二)

--LinuxCPP1305

-13.06 进程管理(三)

--LinuxCPP1306

-13.07 进程间通信(一)

--LinuxCPP1307

-13.08 进程间通信(二)

--LinuxCPP1308

-13.09 进程间通信(三)

--LinuxCPP1309

-13.10 进程间通信(四)

--LinuxCPP1310

-13.11 进程池

--LinuxCPP1311

-13.12 编程实践

--LinuxCPP1312

-第十三讲 进程编程--编程实践提交入口

第十四讲 线程编程

-14.1 提纲

--LinuxCPP1401

-14.2 线程基本概念

--LinuxCPP1402

-14.3 线程管理(一)

--LinuxCPP1403

-14.4 线程管理(二)

--LinuxCPP1404

-14.5 线程管理(三)

--LinuxCPP1405

-14.6 线程管理(四)

--LinuxCPP1406

-14.7 线程同步机制(一)

--LinuxCPP1407

-14.8 线程同步机制(二)

--LinuxCPP1408

-14.9 C++11线程库(一)

--LinuxCPP1409

-14.10 C++11线程库(二)

--LinuxCPP1410

-14.11 C++11线程库(三)

--LinuxCPP1411

-14.12 C++11线程库(四)

--LinuxCPP1412

-14.13 C++11线程库(五)

--LinuxCPP1413

-14.14 编程实践

--LinuxCPP1414

-第十四讲 线程编程--编程实践提交入口

第十五讲 网络编程

-15.1 提纲

--LinuxCPP1501

-15.2 Internet网络协议

--LinuxCPP1502

-15.3 套接字(一)

--LinuxCPP1503

-15.4 套接字(二)

--LinuxCPP1504

-15.5 编程实践

--LinuxCPP1505

-第十五讲 网络编程--编程实践提交入口

课程文档

-课程PDF文件

LinuxCPP0507笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。