【代码大全】 读书笔记

第七章 高质量的子程序

子程序 routine

子程序的目的: 子程序只完成一件事,提高程序的可管理性、可读性、可修改性。

高内聚性:是指子程序中各种操作之间联系的紧密程度。

函数与过程的区别:

  • 函数是有return返回值的;函数的名字应该描述其返回值
  • 过程没有返回值,或者返回类型为void;过程的名字应该是 动词+宾语
1.创建子程序的理由
  • 降低复杂度
  • 避免代码重复
  • 简化复杂的逻辑操作
  • 隐藏实现细节
  • 创建简单好用的子程序
2.内聚性

功能内聚性:一个子程序仅执行一项操作,比如 cos

不好的内聚性:通信内聚性、时间内聚性、逻辑内聚性、过程内聚性

3.好的子程序名字
  • 不要仅通过数字来描述子程序名字
  • 过程起名时使用动词+宾语
    如 PrintDocument()
  • 子程序的总长度最在150行以内
4.子程序的参数
  • 按照输入-修改-输出的顺序排列参数

C++中用CONST关键字定义输入参数合适

  • 如果几个子程序都使用了类似的参数,应该使这些参数的排列顺序保持一致
  • 状态或者布尔变量放到参数的最后
  • 不要把子程序的参数用做工作变量
// 正确的使用方法  引入工作变量 workValue
int Sample(int input)
{
    int workValue=input*input;
    return workValue;
}

5.使用函数时要注意的问题
  1. 写函数时,写一个状态变量作为显示参数的过程
    例如:
report.FormatOutput(formattedReport,outputStatus)
{  if(outputStatus=success)
    then
}

2. 设置函数返回值注意事项:

  • 检查所有可能的返回路径,初始化返回值
  • 不要返回指向局部数据的引用或指针
    3.宏子程序
  • 把宏表达式整个包含在括号内
  • 把包含多条语句的宏用大括号括起来

第八章 防御式编程

概念:子程序应该不因传入错误数据而被破坏,哪怕是由其他子程序产生的错误数据。

1.保护程序免遭非法输入数据的破坏
  • 检查外部数据,如接口数据
  • 检查所有的输入数据
  • 决定如何处理错误的输入数据
2.断言 assertions

断言用于处理代码中不应该发生的错误,是用在开发和维护期间使用的,通常是一个子程序或宏。

断言包括两个参数:一个描述假设为真时的情况的布尔表达式,和另一个断言为假时需要显示的信息。

assert denominator!=0:"denominator is unexpectedly equal to 0.";


char *strcpy(char *strDest, const char *strSrc)
{
 char *address = strDest;
 assert((strDest != NULL) && (strSrc != NULL));
 while ((*strDest++ = *strSrc++) != ’\0’)
  ;
 return address;
}

其中包含断言assert( (strDest != NULL) && (strSrc != NULL) ),它的意思是源和目的字符串的地址都不能为空,一旦为空,程序实际上就执行错误了,会引发一个abort。

3.错误代码的处理

当系统遇到错误时,要决定系统里哪些部分应该直接处理错误,哪些部分只报告所发生的错误。
遇到错误时的处理方法:

  • 返回中立值;
  • 换用下一个正确的数据;
  • 换用最接近的合法值;
  • 返回与前次相同的数据;
  • 把警告信息记录到日志文件中;

理解程序的正确性和健壮性

架构层次上决定使用对错误的处理方法,比如让高层的代码处理错误,底层的代码只需报告错误。

在每个系统调用后检查错误码,一旦检测到错误,就记下错误代号和它的描述信息。

4.异常的处理 exception

子程序使用throw抛出一个异常对象,再被调用链上层其他子程序的try-catch语句捕获

5.各种错误的处理机制:
  • 在局部处理错误
  • 使用错误码传递错误
  • 在日志文件中记录调试信息
  • 关闭系统等

第十章 使用代码的一般事项

变量初始化原则
  1. 关闭隐式声明,隐式声明函数带来问题;
    隐式声明

  2. 声明全部的变量

  • 声明变量的时候初始化;
  • 在靠近变量第一次使用的位置初始化它;
  • 可能的情况使用const或者final;
  • 需要重新初始化的代码位于重复执行的代码内部; 双重for循环,重新初始化计数变量
  • 在程序开始时初始化工作内存;
作用域 : 使变量引用局部化

变量声明和定义时要同时减小变量跨度和生存时间

先选择小的作用域

第十一章 变量名的力量

1.注意事项
  1. 对变量的描述就是最好的变量名,例如:seatCount 小写字母+大写首字母
  2. 变量声明要容易理解,最好时整个英语单词的描述,而不是简称,比如 当前日期 currentDate,而不是date。
  3. 避免使用常用的名字作为变量名,如date,time等
  4. 好的名字表达是“什么”what,而不是“如何”how,比如:calcVal比sum的计算痕迹明显
  5. 变量名控制在9-16个字符内,确保含义清晰
正好:numTeamMembers,seatCount
太短:m,n,max
  1. 表示计算值的限定词,比如Total,Sum,Average,这类限定词加到名字的最后。
  2. 变量名中最重要的那部分一般放在最前面,比如:revenueToal,expenseTotal;
  3. 表示总数时用Count,customerCount;表示索引时用Index,customerIndex;来代替Num
2.变量的命名

循环变量的命名:

  • 简单的循环变量:i,j,k
  • 变量在循环外使用:recordCount
  • 嵌套循环时:teamIndex,eventIndex

状态变量的命名:

不要使用Flag,使用枚举类型和具名常量,

const int PRINTABLE_CHAR=0x04
if(characterType & PRINTABLE_CHAR)

临时变量

  • 临时变量也要有自己的名字,不要使用temp

布尔变量

  • 有用的布尔变量名:表示0 1 状态的名字:done,error,found,ok,success
  • 给布尔变量赋予隐含的“真假”含义名字,sourceFileFound
3.非正式命名规则

命名规则能够区分局部数据、类数据、全局数据,还应该可以区分类型名、具名常量、枚举类型名和变量名。

  • 区分变量名和子程序名字:变量名以字母小写开始,子程序名以字母大写开始;
    variableName; RoutineName()
  • 区分类和对象;
    Widget employeeWidget;
    LongerWidget fullEmployeeWidget;
  • 全局变量,加上g_前缀,g_RunningTotal
  • 成员变量,加上m_前缀
  • 标识具名常量,包括typedef,全部大写,用下划线分割
  • 标识类型声明,加上t_前缀,t_Color
  • 标识枚举类型的元素,加上e_前缀,同时该类型的成员名加上基于该类型的前缀,如Color_
  • 在不能保证输入参数是只读变量的语言里标识只读参数,如在C++里,使用 & const*,const前缀不能出现在赋值符号左边
  • 格式化命名 大小写命名或者分隔符,我使用大小写命名,第一个字母为小写

命名规则实例:

在这里插入图片描述
在这里插入图片描述

4.标准前缀
  • UDT 用户自定义类型缩写

  • 标准前缀,比如:p g i min max lim first last

  • 避免在名字中使用数字,比如 file1,file2

  • 避免在名字中包含容易混淆的字符,比如数字1和小写字母l,1和I,0和O,2和z,5和S,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值