作业(三)
团队:
许郁杨 031602240
盖嘉轩 031602211
设计思路部分主要是整个程序的总结和对上一篇的补充。
编码规范部分我们进行过比较粗略地讨论,这里对有讨论的内容进行了比较完整的整理。
实现设计思路
程序实现的大致思路是:读取需求、生成表达式、计算表达式、读入答案、检验并输出。下面进行具体描述:
读取需求,主要放在main.cpp中,对表达式的可选择项细分,由用户选择所需的生成结果,可选择项包括:
- 语言:中文和英文;
- 是否包含乘除;
- 是否包含分数;
- 是否包含括号;
- 参数的大小范围。
生成表达式,主要放在generate.cpp中,实现了随机数生成和表达式生成的功能。具体细节:
- 通过调用系统时间作为随机数种子,尽量做到“随机”;
- 对表达式的各个组成部分和各种情况进行充分讨论,使表达式能做到尽量随机;
- 通过一次最多只生成两个参数和一个符号的方式,实现了丰富的表达式形式,如括号中包含多个参数、括号嵌套等;
- 通过对每次生成的表达式进行检验、保存,保证了不出现重复的表达式;
- 对分数加括号,而表达式使用中括号,区分优先级。
计算表达式,主要在fraction.cpp和stack.cpp中实现,实现了分数部分的类实现和对表达式的转换、计算。
分数部分细节:
- 对分子和分母都进行int和string两种类型的保存,使用stringstream进行了类型转换,使数据处理更加方便;
- 将整数转换为分数处理,方便进行计算;
- 实现了分数类的操作符重载。
栈部分细节:
- 表达式转换中使用堆栈容器作为运算符栈;
- 表达式计算中使用分数类数组作为数栈;
读入答案、检验并输出,主要放在verify.cpp中,实现了判重、答案检验和输出的功能,同时实现了统计正误个数的功能。
编码规范
1.命名
变量命名:
- 全部使用小写字母;
- 使用相近的英文或英文前缀;
- 使用简单易懂的名词;
- 避免数据类型的强制转换;
- i、j作为循环变量,tmp作为临时变量、flag作为标识变量,point作为指针变量;
- 一些常见名词:low、high、down、up、first、last、correct、wrong、answer。
函数命名:
- 适用驼峰法,如:void addUsers();
- 使用其包含的功能作为函数名;
- 使用清晰易懂的单词。
类命名:
- 首字母大写;
- 使用简单易懂的名词。
常量及宏定义命名:
- 全部使用大写字母;
- 以下划线'_'分割单词。
2.排版
- 一行只写一条语句;
- 缩进空格为4个空格;
- 相互独立的模块之间添加空行;
- '{'、'}'各自单独为一行。
3.注释
- 使用中文;
- 文件说明放在顶端,'/* '、'*/'进行注释;
- 函数和语句说明放在对应函数名和语句的同一行行末,使用'//'注释;
- 注释应简洁易懂。
4.函数
- 函数功能应该独立明确;
- 控制单个函数的长度不过长;
- 除空函数和构造函数,其他函数都应有返回值;
- 不得直接修改函数参数。
5.文件
- 统一保存为.cpp或.h文件;
- 统一使用UTF-8编码;
程序实现和结果测试的截图
中文:
英文:
2.3版本(保证结果为整数、可选择表达式中数字的个数)
中文:
英文:
github的提交链接和提交日志截图
Git提交日志
GitHub提交日志
团队:
个人:
分工和协作证据截图
分工方面,我主要负责fraction.cpp和stack.cpp,队友主要负责head.h、main.cpp、generate.cpp、verify.cpp,一般代码完成后都会由我检查、修改部分错误并上传,所以两人GitHub上的记录会有点不平衡。
QQ聊天记录
合作过程
合作的过程大致符合上一篇中的日程规划。
确定合作之后,我们就先去熟悉多源文件的编写,同时我开始构思整个程序的大体架构。经过交流和讨论,我们在6号确定了文件分工,并确定了日程规划。然后,我们分别对各自负责部分的所需功能和函数进行分类命名,确定变量的命名,最后汇总。11号,我在GitHub上建立了团队并上传第一版fraction.cpp。期间我们对各自编写,遇到问题相互交流,并学习GitHub团队协作的用法。14号,我们上传了第一版完整程序至develop。检测程序并修复后,我们上传了1.0版本至master。15号,我们修改一些错误,并增加了中英文切换的功能后,上传了2.0版本至master。16号,我修改一个错误,对排版进行调整,并新增一些注释后,上传了2.1版本至master。
日程规划:
合作体会
在合作中我更加理解了一件事,就是对方其实很难真的理解你的思路、想法。所以我们才更需要统一的工作标准和方向,不让代码跑偏,最好要有一个“主心骨”。因为,信任队友,不代表能信任队友的代码。团队成员间的知识、经验各不相同,组合在一起就容易出现偏差。作为团队中的一员,不能只是随着自己的性子,不能单纯认为完成规划的任务就行,而是要积极地参与进团队中,认真地对待手中的程序,愿意学习、愿意交流。当然,完成规划的要求是最基本的,但不应满足于此。毕竟,如果队友直接把过不了编译的程序上传,你肯定是会生气的。
接下来说一些感到不足的地方:
模块化
我从来没有写过这个规模的程序,所以一开始划分模块的时候简直一脸懵逼。虽然硬着头皮一步步做下来了,但其中还遗留了非常多的问题。比如,.h文件中不应包含过多头文件。一开始我根本没想到这个问题,直到GitHub上出了conflicts。。最后不得已把文件删除了才能重新上传。这也反映出我事前没有做好模块化的问题,后期不断增删头文件和函数,导致错误频出,要引以为戒。
编码规范
由于没有制定完整的编码规范,导致最后的程序显得有些杂乱。特别是一些基本的注意点,比如二元运算符前后空格之类的,完全没有做到。函数和变量的命名也不够清晰美观。这也是前期工作没到位的体现。
面向对象
就如前面说的,事前的模块化做得太糟糕,以致各个模块不够独立,常常是改了一个函数,连带好几个一起受牵连,而且函数的功能不够明确,有相互交集。还有分数类,简直是直接当普通的函数在用了。就像学长说的,这是在以面向对象之虚而行面向过程之实。以后还要继续实践。
GitHub协同合作
由于是新手,有很多地方不熟悉,就像conflicts,一开始根本不知道从何下手,后来才反应过来是头文件和函数定义的问题。而且很多操作还是在本地进行的,基本只是把它当作了云盘。。同样地,今后会继续学习实践。
正如盛田先生所说,所有我们完成的美好事物,没有一件是可以迅速做成的——因为这些事物都太难,太复杂。希望以后能不要如此急躁,让自己的程序真的成为一个“美好事物”。