迅雷下载:ftp://222.214.218.42/20060908/49c42164-78d6-45dc-9a76-9984bdba4d73.pdf
1.简单的Windows应用程序命名规则:
【规则】类名和函数名用大写字母开头的单词组合而成。
例如:
class Node; // 类名
void SetValue(int value); // 函数名
【规则】变量和参数用小写字母开头的单词组合而成。
例如:
BOOL flag;
int drawMode;
【规则】常量全用大写的字母,用下划线分割单词。
例如:
const int MAX = 100;
const int MAX_LENGTH = 100;
【规则】静态变量加前缀s_(表示static)。
例如:
static int s_initValue; // 静态变量
【规则】全局变量加前缀g_(表示global)。
【规则】类的数据成员加前缀m_(表示member),这样可以避免数据成员与成员函数的参数同名。
2.允许复合表达式存在的理由是:(1)书写简洁;(2)可以提高编译效率。但要防止滥用复合表达式。
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为假
其它的用法都属于不良风格,例如:
if (flag == TRUE)
if (flag == 1 )
if (flag == FALSE)
if (flag == 0)
对于林锐提出的规则我有质疑,既然bool型的值按定义记为FALSE和TRUE,
那么我根本不关心FALSE和TRUE的具体值,那么
if (flag == TRUE)
又有何不可?系统总不会把TRUE定义为0吧?(如果是这样,林锐还是对的)
4.整型变量与零值比较:
【规则】应当将整型变量用“==”或“!=”直接与0比较。
与零值比较的标准if语句如下:
if (value == 0)
if (value != 0)
不可模仿布尔变量的风格而写成
if (value) // 会让人误解 value是布尔变量
if (!value)
5.浮点变量与零值比较:
if ((x>=-EPSINON) && (x<=EPSINON))
6.指针变量与零值比较:
if (p == NULL) // p与NULL显式比较,强调p是指针变量
if (p != NULL)
7.为防止出错:
为了防止将 if (p == NULL) 误写成 if (p = NULL),而有意把p和NULL颠倒。
编译器认为 if (p = NULL) 是合法的,但是会指出 if (NULL = p)是错误的,
因为NULL不能被赋值。
if (condition) //不良风格,容易出错
return x;
return y;
改写为
if (condition)
{
return x;
}
else
{
return y;
}
或者改写成更加简练的
return (condition ? x : y);
8.循环语句的效率:
【建议】在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最外层,以减少CPU跨切循环层的次数。
【建议】如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体的外面。
如果老要进行逻辑判断,打断了循环“流水线”作业,使得编译器不能对循环进行优化处理,降低了效率。
但缺点是:程序不简洁.
9.【建议】建议for语句的循环控制变量的取值采用“半开半闭区间”写法。
x值属于半开半闭区间“0 =< x < N”,起点到终点的间隔为N,循环次数为N。非常直观简洁.
10.【规则】不要忘记最后那个default分支。即使程序真的不需要default处理,也应该保留语句
default : break;
这样做并非多此一举,而是为了防止别人误以为你忘了default处理。
11.goto的讨论:
很多人建议废除C++/C的goto语句,以绝后患。但实事求是地说,错误是程序员自己造成的,不是goto的过错。goto 语句至少有一处可显神通,它能从多重循环体中咻地一下子跳到外面,用不着写很多次的break语句;
就象楼房着火了,来不及从楼梯一级一级往下走,可从窗口跳出火坑。所以我们主张少用、慎用goto语句,而不是禁用。
12.常量的讨论:
C语言用 #define来定义常量(称为宏常量)。
C++ 语言除了 #define外还可以用const来定义常量(称为const常量)。
在C++中,const定义常量的优势:
1)类型检查
2)可以调试
故可以规定:
【规则】在C++ 程序中只使用const常量而不使用宏常量,即const常量完全取代宏常量。
【规则】需要对外公开的常量放在头文件中,不需要对外公开的常量放在定义文件的头部(cpp文件)。
为便于管理,可以把不同模块的常量集中存放在一个公共的头文件中。
类中使用const常量:
1)不能在类声明中初始化const数据成员。
因为类的对象未被创建时,编译器不知道该成员的值是什么。
const数据成员的初始化只能在类构造函数的初始化表中进行.
2)const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的,
因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。
3)怎样才能建立在整个类中都恒定的常量呢?
别指望const数据成员了,应该用类中的枚举常量来实现。
但是缺点很明显,只能表示有限大小的整型值.
13.函数设计:
C语言中,函数的参数和返回值的传递方式有两种:
值传递(pass by value)和指针传递(pass by pointer)。
C++ 语言中多了引用传递(pass by reference)。
14.风格:
【规则】:
void SetValue(int width, int height); // 良好的风格
void SetValue(int, int); // 不良的风格
float GetValue(void); // 良好的风格
float GetValue(); // 不良的风格
【规则】参数命名要恰当,顺序要合理。
一般地,应将目的参数放在前面,源参数放在后面。
如果将函数声明为:
void StringCopy(char *strDestination, char *strSource);
【规则】如果参数是指针,且仅作输入用,则应在类型前加const,以防止该指针在函数体内被意外修改。
例如:
void StringCopy(char *strDestination,const char *strSource);
【规则】如果输入参数以值传递的方式传递对象,则宜改用“const &”方式来传递,这样可以省去临时对象的构造和析构过程,从而提高效率。
@#$%:const & 怎么用?
【规则】不要将正常值和错误标志混在一起返回。正常值用输出参数获得,而错误标志用return语句返回。
典型的getchar函数:
可由 int getchar(void); //字符型值和终止值EOF一同返回,不良风格,但用起来方便
改为 BOOL GetChar(char *c);
【建议】有时候函数原本不需要返回值,但为了增加灵活性如支持链式表达,可以附加返回值。
char *strcpy(char *strDest,const char *strSrc);