第四章 建立子程序的步骤
4.1 建立程序步骤概述
4.2 程序设计语言(PDL)
PDL语言也就是所谓的打印语言,也可称为伪码或结构化语言,功能强大,能输出复杂的页面和图像,但由于其复杂性处理起来的速度也相对较慢
使用PDL的益处:
- PDL可以使评审工作变得更容易
- PDL可以帮助实现逐步细化的思想
- PDL使得变动工作变得很容易
- PDL极大地减少了注释工作量
- DL比其它形式的设计文件容易维护
4.3 设计子程序
创建一个子程序的第一步 设计
检查先决条件
定义这个子程序将要解决的问题
给子程序命名
考虑效率
研究算法和数据结构
编写PDL
编写工作应该从抽象到具体
考虑数据
检查PDL
逐步细化
4.4 子程序编码
- 书写子程序说明
- 非正式地检查代码: 一旦完成了对某一子程序的实现,停下来检查一下是否有误
- 进行收尾工作: 检查子程序的质量
- 检查子程序的接口
- 检查通用设计质量
- 检查子程序的数据
- 检查子程序的控制结构
- 检查子程序设计
- 检查子程序的文档
- 按需要重复步骤: 如果程序的质量很差,请返回PDL阶段
4.5 检查子程序
1. 在心里对子程序进行查错处理:
在前面提到过的非正式检查和清扫工作就是两种内心检查方法,另一方法是在心中执行每一个路径。
2.编译子程序:
尽可能把编译程序的警告级别调到最高;消除所有编译程序指出的错误和提出警告的原因。
3.使用计算机来检查子程序错误:
子程序编译之后,将其放入调试程序,逐步运行每一行代码,要保证每一行都是按预期的运行。
4.消除子程序中的错误:
一旦发现有错误,就要消除它。
金句
- 项目成功的关键就是在投资最少时找出错误,以降低改错成本
- 好的子程序名字是一个高质量软件的标志之一
- 高质量的程序是一个逐步化的过程
- 实现了子程序后进行代码的检查,此时发现并改正错误成本会很低
- 发现程序中错误异常特别多,那么就重新开发一个,不要试图去修补它
- 修补往往意味着不充分的理解,而且会在现在和将来产生更多的错误
第五章 高质量子程序特点
5.1 生成子程序的原因
- 降低复杂性
- 避免重复代码段
- 限制改动带来的影响
- 隐含顺序
- 改进性能
- 进行集中控制
- 隐含数据结构
- 隐含指针操作
- 隐含全局变量
- 促进重新使用代码段
- 计划开发一个软件族
- 改善某一代码段可读性
- 改善可移植性
- 分隔复杂操作
- 独立非标准语言函数的
- 简化复杂的布尔测试
5.2 子程序名称恰当
一个恰当的子程序名称应该清晰地描述出子程序所作的每一件事。
- 对于过程的名字,可以用一个较强的动词带目标的形式。
- 对于函数名字,可以使用返回值的描述。
避免无意义或者模棱两可的动词 。
描述子程序所做的一切。
名字的长度要符合需要(15-20)
建立用于通用操作的约定。
如果子程序是关于直接输入的,就在其名称前面加一个“Get”前缀,如果是非直接输入的则加“Query”前缀,这样,返回当前输入字符的 GetlnputChar()将清除输入缓冲区.而同样是返回当前输入字符的 QuerylnPutChar()则不清除缓冲区。
5.3 强内聚性
5.3.1 可取的内聚性
- 功能内聚性:是最强也是最好的一种内聚,当程序执行一项并且仅仅是一项工作时,就是这种内聚性。
- 顺序内聚性:顺序内聚性是指在子程序内包含需要按特定顺序进行的、逐步分享数据而又不形成一个完整功能的操作
-
通讯内聚性:两个操作只是使用相同数据,而不存在其它
任何联系时产生的。 - 临时内聚性:是指含有一些因为需要同时执行才放到一起的操作。
5.3.2 不可取的内聚性
- 过程内聚性:把一组操作赋予特定的顺序,而在该子程序内,这些操作并没有原因彼此关联
- 逻辑内聚性:若干缺乏逻辑关联操作被放入同一子程序中,通过传入的控制标志选择执行其中的一项。(处理为事物处理中心)
- 偶然内聚性:子程序中的各个操作没有什么关联。
5.4 松散耦合性
耦合性指的是两个子程序之间联系的紧密程度。
5.4.1 耦合标准
- 耦合规模:两个子程序之间联系的数量多少。
- 密切性:两个子程序之间联系的直接程度
- 可见性:两个子程序之间联系的显著程度
- 灵活性:改变两个子程序之间联系的容易程度
5.4.2 耦合层次
- 简单数据耦合:两个子程序之间通过参数表的形式传递非结构化数据。(最好的耦合)
- 数据结构耦合:传递的数据试结构化的。
- 控制耦合:逻辑内聚性
- 全局数据耦合:两个子程序使用同一个全局变量
- 不合理耦合:果一个子程序使用了另外一个子程序中代码,或者它改变了其中的局部变量
5.5 子程序长度
当子程序长度是100到150行时,错误率最低。
在超过 500 行之后,错误数量会与子程序的长度成正比
5.6 防错性编程
最有效的防错性编码途径是一开始就不要引入错误。可以采用逐步设计方法、在编码前先写好 PDL、进行低层次设计、审查等都可以防止错误引入。
5.7 子程序参数
子程序间的接口往往是一个程序中最容易出错的部分
- 确保实际参数与形式参数匹配
- 按照输入一修改一输出的顺序排列参数
- 如果几个子程序今使用了相似的参数,应按照不变的顺序排到这些参数 fprintf()函数与 printf()函数相比,只多了一个文件作为第一变量
- 使用所有的参数
- 把状态和“错误”变量放在最后
- 不要把子程序中的参教当作工作变量: 用局部变量代替
- 把一个子程序中的参数个数限制在7个左右
- 考虑建一个关于输入、输出和修改参数的命名约定
- 仅传递子程序需要的那部分结构化变量
- 不要对参数传递作出任何设想(如果你直接与参数打交道,事实上就已经注定了你的程序不可能在另一个机器上运行。)
5.8 使用函数
函数永远应该以它的返回值来命名,如果一个子程序的用途就是返回一个由它名字指示的值,那么就用函数,否则使用过程。
5.9 宏子程序
把宏表达式整个包含在括号里
把含有多条语句的宏用大括号括起来
用给子程序命名的方法来给展开后的宏命名,以便在需要时可以把宏替换为子程序