c语言提高质量(上)

对高质量c编程(林锐)总结(上)1—5章

软件开发人员需对程序正确性、健壮性、可靠性、效率、易用性、可读性(可理解性)、可扩展性、可复
用性、兼容性、可移植性等质量属性了解并应用

第一章 文件结构
1.版权
版权和版本的声明位于头文件和定义文件的开头(参见示例 1-1),主要内容有:
(1)版权信息。
(2)文件名称,标识符,摘要。
(3)当前版本号,作者/修改者,完成日期。
(4)版本历史信息
c语言提高质量(上)
2.文件
头文件:【规则 1-2-1】为了防止头文件被重复引用,应当用 ifndef/define/endif 结构产生预处
理块。【规则 1-2-2】用 #include <filename.h> 格式来引用标准库的头文件 。用 #include “filename.h” 格式来引用非标准库的头文件 【建议 1-2-1】头文件中只存放“声明”而不存放“定义” 【建议 1-2-2】不提倡使用全局变量
头文件的作用 :
(1) 调用库功能。在很多场合,源代码不可向用户公布时,只要向用户提供头文件和库即可。用户只需要按照头文件中的接口声明来调用库功能。
(2)头文件能加强类型安全检查。如果某个接口 与头文件中的声明不一致,编译器就会指出错误 。

第二章 程序板式
1.空行
【规则 2-1-1】函数(类)之间加空行 【规则 2-1-2】 函数体内,逻揖上密切相关的语句之间不加空行,否则加。
2.代码
【规则 2-2-1】一行代码只做一件事情,如只定义一个变量,或只写一条语句【规则 2-2-2】if、for、while、do 等语句自占一行。下面都要加{} 。
3.空格
【规则 2-3-1】 const、virtual、inline、case 等关键字之后 留一个空格。象 if、for、while 等关键字之后应留一个空格再跟括号‘(’ ,区别:函数名之后不要留空格,紧跟左括号‘(’【规则 2-3-3】‘(’向后紧跟‘;’ 等符号【规则 2-3-4】‘,’之后要留空格,如 Function(x, y, z)。, for (initialization; condition; update)。
【规则 2-3-5】 ,如“=”、“+=” “>=”、“<=”、“+”、“*”、“%”、“&&”、“||”、“<<”,“^”等二元操作符的前后应当加空格。区别:一元操作符如“!”、“~”、“++”、“–”、“&”(地址运算符)等前后不加空格。同时:象“[]”、“.”、“->”这类操作符前后不加空格。【建议 2-3-1】对于表达式比较长的 for 语句和 if 语句,为了紧凑起见可以适当地去掉一些空格,如 for (i=0; i<10; i++)和 if ((a<=b) && (c<=d))
看表更方便易懂
黄色为需要加空格,绿下划线为不需加空格处c语言提高质量(上)
4. 对齐
【规则 2-4-1】程序的分界符‘{’和‘}’应独占一行并且位于同一列,同时与它们的上一行左对齐。
【规则 2-4-2】{ }之内的代码块在‘{’右边数格处左对齐,如果出现嵌套的{},则使用缩进对齐
5. 长行拆分
【规则 2-5-1】代码行最大长度宜控制在 70 至 80 个字符以内。
【规则 2-5-2】长表达式在低优先级操作符处拆分 ,操作符放在新行之首 。 新行缩进,使排版整齐
c语言提高质量(上)
6.修饰符:应当将修饰符 * 和 & 紧靠变量名
例如:
char *name;
int *x, y; // 此处 y 不会被误解为指针

7.注释:写函数前先写注释注明函数作用,变量等信息
例如:
c语言提高质量(上)
注释应准确易懂,简练不可太多,注释放在代码的上方或右方,不可放在下方
当代码比较长,特别是有多重嵌套时,应当在一些段落的结束处加注释
c语言提高质量(上)

8.类:类可以将数据和函数封装在一起,类提供关键字 public、protected 和 private,分别用于声明哪些数据和函数是公有的、受保护的或者是私有的。
将 public 类型的函数写在前面,而将 private 类型的数据写在后面,“以行为为中心”,重点关注的是类应该提供什么样的接口(或服务)因为用户最关心的是接口
c语言提高质量(上)
第三章 变量函数命名规则
1.“匈牙利”法:“在变量和函数名中加入前缀以增进人们对程序的理解”。如所有的字符变量均以 ch为前缀,若是指针变量加前缀 p。eg:一个变量由 ppch 开头,则 它是指向字符指针的指针
2.标识符应当直观 可望文知意 。最好采用英文单词或其组合,切忌使用汉语拼音
【规则 3-1-4】程序中不要出现仅靠大小写区分的相似的标识符。
例如:int x, X; 或void foo(int x); 与void FOO(float x);
【规则 3-1-5】程序中不要出现标识符完全相同的局部变量和全局变量
【建议 3-1-1】尽量避免名字中出现数字编号,如 Value1,Value2 等
【规则 3-2-1】类名和函数名用大写字母开头 ;变量和参数用小写字母开头 ;常量全用大写的字母,用下划线分割单词;静态变量加前缀 s_(表示 static);如果不得已需要全局变量, 加前缀 g_(表示 global)。
【规则 3-2-6】类的数据成员加前缀 m_(表示 member),这样可以避免数据成员与成员函数的参数同名
例如:
void Object::SetValue(int width, int height)
{
m_width = width;
m_height = height;
}

第四章 表达式和基本语句
1.优先级: 运算符比较多,用括号确定 操作顺序,避免使用默认的优先级
2.复合表达式:
【规则 4-2-1】不要编写太复杂的复合表达式。例如:i = a >= b && c < d && c + f <= g + h ;
【规则 4-2-2】不要有多用途的复合表达式。
例如:
d = (a = b + c) + r ;
该表达式既求 a 值又求 d 值。应该拆分为两个独立的语句:
a = b + c;
d = a + r;
【规则 4-2-3】不要把程序中的复合表达式与“真正的数学表达式”混淆。
例如: if (a < b < c) // a < b < c 是数学表达式而不是程序表达式,并不表示 if ((a<b) && (b<c))
而是 if ( (a<b)<c )

3.if语句:
【规则 4-3-1】假设布尔变量名字为 flag,它与零值比较的标准 if 语句如下:
if (flag) // 表示 flag 为真;if (!flag) // 表示 flag 为假
其它的用法都属于不良风格,例如:

if (flag == TRUE) 或 if (flag == 1 ) 或 if (flag == FALSE) 或 if (flag == 0)
【规则 4-3-2】 整型变量用“”或“!=”直接与 0 比较,不用boll类型
假设整型变量的名字为 value,它与零值比较的标准 if 语句如下:
if (value == 0)
if (value != 0)
区别:浮点变量 不可用“
”或“!=”与任何数字比较。因为float 还是 double 类型的变量,都有精度限制,应该设法转化成“>=”或“<=”形式
例如:
float x=1.1;
if (x == 0.0) // 隐含错误的比较
应转化为
if ((x>=-EPSINON) && (x<=EPSINON)) 其中 EPSINON 是允许的误差范围(精确度)
【规则 4-3-4】应当将指针变量用“==”或“!=”与 NULL 比较。指 假设指针变量的名字为 p,它与零值比较的标准 if 语句如下:
if (p == NULL) // p 与 NULL 显式比较,强调 p 是指针变量
if (p != NULL
)
注意: 1.if (NULL == p) 这样 的格式 是程序员为了防止将 if (p == NULL) 误写成 if (p = NULL),而有意把 p 和 NULL 颠倒。因为 NULL 不能被赋值,if (NULL = p)是错误的。
2.return (condition ? x : y); 与 if …else…等价,前者更简练

  1. 循环语句效率:
    【建议 4-4-1】在多重循环中, 将最长的循环放在最内层,最短的循环放在最外层,以减少 CPU 跨切循环层的次数
    c语言提高质量(上)
    【建议 4-4-2】如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体的外面。
    c语言提高质量(上)
    5.for循环控制变量:
    【规则 4-5-1】不可在 for 循环体内修改循环变量,防止 for 循环失去控制。
    例 如:for (int i=0; i<10; i++)
    {
    i=i+10;
    }
    【建议 4-5-1】建议 for 语句的循环控制变量的取值采用“半开半闭区间”写法
    例如:for (int x=0; x<N; x++) 修改为for (int x=0; x<=N-1; x++)

6.switch语句
1.switch 是多分支选择语句 。虽然可以用嵌套的 if语句来实现多分支选择,但 冗长难读。这是 switch 语句存在的理由。
2. switch 语句的基本格式是:
switch (variable)
{
case value1 : …
break;
case value2 : …
break;

default : …
break;
}
【规则 4-6-1】每个 case 语句的结尾不要忘了加 break,否则将导致多个分支重叠(除非有意使多个分支重叠)。
【规则 4-6-2】不要忘记最后那个 default 分支。即使程序真的不需要 default 处理,也应该保留语句 default : break;

7.goto语句:
1.goto 语句可以灵活跳转,但goto 语句经常带来错误或隐患:它可能跳过了某些对象的构造、变量的初始化、重要的计算等语句
2. 。goto 语句 能从多重循环体中 一下子跳到外面,用不着写很多次的 break 语句; 例如
{ …
{ …
goto error;
}
}
error: