编程格调
Programming Style
表达
- 如何表达每一个语句很大程度上决定了程序本身是否易于理解,语句的完美表达是用任何注释、格式规范或补充文档都无法替代的。
- 简单直接地表达你要说的意思
- 使用库函数
- 避免使用临时变量
- 代码要清晰,不要为了“效率”牺牲可读性
- 让机器干脏活
- 用函数调用替代重复的表达式
- 加括号来避免歧义
- 选择不会被混淆的变量名
- 避免不必要的冲突
- 使用语言好的特性,避免使用不好的特性
- 不要使用条件分支来代替一个逻辑表达式
- 用“电话测试”来检查可读性
控制结构
- 用
IFELSE
强调两个操作只有一个被执行 - 用
DO
和DOWHILE
来强调循环的存在 - 确保你的程序是自顶向下阅读的
- 使用
IF...ELSEIF...ELSEIF...ELSE
来实现多路分支 - 使用基本的控制结构
- 先用容易理解的伪语言编写代码,然后再翻译成你需要使用的语言
- 避免使用
ELSEGOTO
和ELSERETURN
- 判断要尽可能挨着与之相关的操作
- 使用数组来避免重复的控制流
- 选择可以简化程序的数据表示方法
- 不要止步于第一遍的代码草稿
程序结构
- 模块化,使用子例程
- 让模块之间的耦合变得可见
- 每一个模块都应该做好一件事
- 确保每一个模块都隐藏好一些东西
- 以数据为向导来构建程序的结构
- 不要修补蓝代码————重写它
- 分块编写和测试大的程序
- 对于递归定义的数据结构使用递归过程
输入输出
- 校验输入的合法性和合理性
- 保证输入的数据不会违背程序的限制
- 利用文件结束符或结束标志来终止输入,不要让用户去计数
- 识别出非法输入数据,如果可能则纠正之
- 使用统一的形式处理文件结束条件
- 让输入数据易于准备,并让输出数据意义不言自明
- 使用统一的输入格式
- 让输入数据易于校对
- 尽可能选择自由格式输入
- 使用含义自明的输入,指定默认值,将以上二者输出
- 将输入与输出局限在子例程中
- 确保所有的变量在使用之前都被初始化
- 不要停留在一个 bug 上
- 在边界值上测试程序
- 预防性编程
0.1+0.2 != 0.3
- 不要比较浮点数是否相等
- 先做对,再做快
- 再提高程序运行速度时,要保持其正确性
- 先把程序改得更简洁,再提高其运行速度
- 不要为了“效率”上的蝇头小利而牺牲程序的间接性
- 让编译器执行平凡优化
- 不要勉强地复用代码,应该进行改编
- 保证特殊情况真的有特殊性
- 保持简单性,反而会更快
- 不要为了提高速度而画蛇添足————寻找更好的算法
- 在程序中放置测试语句,“增效”之前执行测试
文档
- 确保注释和代码一致
- 不要用注释复述代码做的事情,每个注释都要有实际意义
- 不要注释糟糕的代码————重写它
- 使用含有意义的变量名
- 使用含有意义的语句
- 程序的格式要有助于读者的理解
- 用缩进来体现程序的逻辑结构
- 记录你的数据规划
- 不要过度注释
总结
- 从数据的角度来构造程序
- 既要保证程序效率又要保证可读性,变量和函数应该指明是什么,而不是怎么做
- 在程序结构章节中主要体现单一职责,利用抽象隐藏细节
- 输入输出要保持统一,格式尽可能自由,避免让用户(使用 API 的程序开发人员)记格式
- 好的代码便是文档,好的命名和好的代码结构尤其重要。主要考虑避免重复,自上而下的方法编写程序。