林锐C语言–高质量C/C++编程(第三四章)
林锐C语言--高质量C/C++编程(第三四章)
第三章:命名规则
- 【规则 3-1-1】标识符应当直观且可以拼读,可望文知意,不必进行“解码”。标识符最好采用英文单词或其组合,便于记忆和阅读。
- 【规则 3-1-2】标识符的长度应当符合“min-length && max-information”原则。
- 【规则 3-1-3】命名规则尽量与所采用的操作系统或开发工具的风格保持一致
Windows 简单的命名规则
Windows 应用程序的标识符通常采用“大小写”混排的方式,如 AddChild。而 Unix 应用程序的标识符通常采用“小写加下划线”的方式,如 add_child。
-
【规则 3-1-6】变量的名字应当使用“名词”或者“形容词+名词”。
-
【规则 3-1-7】全局函数的名字应当使用“动词”或者“动词+名词”(动宾词组)。
-
【规则 3-1-8】用正确的反义词组命名具有互斥意义的变量或相反动作的函数等
-
【规则 3-2-1】类名和函数名用大写字母开头的单词组合而成。
-
【规则 3-2-3】常量全用大写的字母,用下划线分割单词。
-
【规则 3-2-4】静态变量加前缀 s_(表示 static)
-
【规则 3-2-5】如果不得已需要全局变量,则使全局变量加前缀 g_(表示 global)。
-
【规则 3-2-6】类的数据成员加前缀 m_(表示 member),这样可以避免数据成员与_成员函数的参数同名。
-
【规则 3-2-7】为了防止某一软件库中的一些标识符和其它软件库中的冲突,可以为各种标识符加上能反映软件性质的前缀。例如三维图形标准 OpenGL 的所有库函数均以 gl 开头,所有常量(或宏定义)均以 GL 开头。
第四章:表达式和基本语句
1)运算符的优先级
C++/C 语言的运算符有数十个,运算符的优先级与结合律如表 4-1 所示。注意一元运算符 + - * 的优先级高于对应的二元运算符。
- 【规则 4-1-1】如果代码行中的运算符比较多,用括号确定表达式的操作顺序,避免使用默认的优先级。
2)复合表达式
如 a = b = c = 0 这样的表达式称为复合表达式。允许复合表达式存在的理由是:
(1)书写简洁;
(2)可以提高编译效率。
但要防止滥用复合表达式。
- 【规则 4-2-1】不要编写太复杂的复合表达式。
例如: i = a >= b && c 003C d && c + f 003C= 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 )。
2)if语句
本节以“与零值比较”为例,展开讨论
- 【规则 4-3-1】不可将布尔变量直接与 TRUE、FALSE 或者 1、0 进行比较。
根据布尔类型的语义,零值为“假”(记为 FALSE),任何非零值都是“真”(记为TRUE)。
TRUE 的值究竟是什么并没有统一的标准。例如 Visual C++ 将 TRUE 定义为1,而 Visual Basic 则将 TRUE 定义为-1。
假设布尔变量名字为 flag,它与零值比较的标准 if 语句如下
- if (flag) 表示 flag 为真
- if (!flag) 表示 flag 为假
整型变量与零值比较
- 【规则 4-3-2】应当将整型变量用“==”或“!=”直接与 0 比较。假设整型变量的名字为 value,它与零值比较的标准 if 语句如下
if (value == 0)
if (value != 0)
浮点变量与零值比较
- 【规则 4-3-3】不可将浮点变量用“”或“!=”与任何数字比较。
千万要留意,无论是 float 还是 double 类型的变量,都有精度限制。
所以一定要避免将浮点变量用“”或“!=”与数字比较,应该设法转化成“>=”或“<=”形式。
假设浮点变量的名字为 x,应当将 if (x == 0.0) 隐含错误的比较
//转化为
if ((x>=-EPSINON) && (x<=EPSINON))
//其中 EPSINON 是允许的误差(即精度)。
- 【规则 4-3-4】应当将指针变量用“==”或“!=”与 NULL 比较。指针变量的零值是“空”(记为 NULL)尽管 NULL 的值与 0 相同但是两者意义不同。假设指针变量的名字为 p,它与零值比较的标准 if 语句如下:
if (p == NULL) // p 与 NULL 显式比较,强调 p 是指针变量 if (p != NULL)
3)循环语句的效率
本节重点论述循环体的效率。提高循环体效率的基本办法是降低循环体的复杂性。
C++/C 循环语句中,for 语句使用频率最高,while 语句其次,do 语句很少用。
- 【建议 4-4-1】在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最外层,以减少 CPU 跨切循环层的次数。
for (col=0; col<5; col++ )
{
for (row=0; row<100; row++)
{
sum = sum + a[row][col];
}
}
- 【建议 4-4-2】如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体的外面。
示例 C 的程序比示例 D 多执行了 N-1 次逻辑判断。并且由于前者老要进行逻辑判断,打断了循环“流水线”作业,使得编译器不能对循环进行优化处理,降低了效率。
for (i=0; i<N; i++) //C
{
if (condition)
DoSomething();
else
DoOtherthing();
}
----//
if (condition) //D
{
for (i=0; i<N; i++)
DoSomething();
}
else
{
for (i=0; i<N; i++)
DoOtherthing();
}
4)for 语句的循环控制变量
【规则 4-5-1】不可在 for 循环体内修改循环变量,防止 for 循环失去控制。
5)switch 语句
switch 是多分支选择语句,而 if 语句只有两个分支可供选择。
虽然可以用嵌套的if 语句来实现多分支选择,但那样的程序冗长难读。这是 switch 语句存在的理由。
- 【规则 4-6-1】每个 case 语句的结尾不要忘了加 break,否则将导致多个分支重叠(除非有意使多个分支重叠)。
- 【规则 4-6-2】不要忘记最后那个 default 分支。即使程序真的不需要 default 处理,也应该保留语句 default : break; 这样做并非多此一举,而是为了防止别人误以为你忘了 default 处理。
switch (variable)
{
case value1:
break;
case value2:
break;
default:
break;
}