for(initialization;condition;update)
{
dosomething();
}
//空行
other();
for(initialization;condition;update)
dosomething();
other();
2.3代码行内的空格(6条规则+1条建议)
【规则2-3-1】关键字之后要留空格。
象const、case等关键字之后至少要留一个空格,否则无法辨析关键字。
象if、for、while等关键字和紧跟的左括号‘(’之后应留一个空格,右括号前也对应要留一个空格,以突出关键字。
例如:
if(a==b)
【规则2-3-2】函数名之后不要留空格,紧跟左括号‘(’,以与关键字区别。
例如:
voidcalc(void);
【规则2-3-3】“,”之后要留空格,如Function(x,y,z)。
如果‘;’不是一行的结束符号,其后要留空格,如for(initialization;condition;update)。
【规则2-3-4】不要在单目运算符(如“!
”、“~”、“++”、“--”、“&”)和其操作对象间加空格。
例如:
!
foo,++i,(long)getValue
【规则2-3-5】赋值操作符、比较操作符、算术操作符、逻辑操作符、位域操作符,如“=”、“+=”、“>=”、“<=”、“+”、“*”、“%”、“&&”、“||”、“<<”,“^”等二元操作符的前后应当加空格。
【规则2-3-6】象“[]”、“.”、“->”这类操作符前后不加空格。
例如:
big.bar,pFile->bar,big[bar]
【建议2-3-1】对于表达式较长的for语句和if语句,为了紧凑起见可以适当地去掉一些空格.
例如:
for(i=0;i<10;i++)和if((a<=b)&&(c<=d))
风格良好的空格
风格不良空格
voidFunc1(intx,inty,intz);
voidFunc1(intx,inty,intz);
if(year>=2000)
if((a>=b)&&(c<=d))
if(year>=2000)
if(a>=b&&c<=d)
for(i=0;i<10;i++)
for(i=0;i<10;i++)
for(i=0;i<10;i++)
x=a
a:
b;
x=a
a:
b;
int*x=&y;
int*x=&y;
array[5]=0;
a.Function();
b->Function();
array[5]=0;
a.Function();
b->Function();
2.4对齐(4条规则)
【规则2-4-1】程序的分界符‘{’和‘}’应独占一行并且位于同一列,同时与引用它们的语句左对齐。
【规则2-4-2】水平缩进每次使用四个空格即可(定义一个tab键为四个空格。
有的要求缩进两个空格)。
【规则2-4-3】同属于一个语句块的代码对齐。
【规则2-4-4】{}之内的代码块在‘{’右边一个tab键处左对齐。
风格良好的对齐
风格不良的对齐
voidFunction(intx)
{
programcode
}
voidFunction(intx){
programcode
}
if(condition)
{
programcode
}
else
{
programcode
}
if(condition){
programcode
}
else{
programcode
}
for(initialization;condition;update)
{
programcode
}
for(initialization;condition;update){
…programcode
}
while(condition)
{
programcode
}
while(condition){
…programcode
}
如果出现嵌套的{},则使用缩进对齐,如:
{
{
}
}
2.5长行拆分(2条规则)
【规则2-5-1】代码行最大长度宜控制在70至80个字符以内。
代码行不宜过长,否则不便于阅读,也不便于打印。
【规则2-5-2】长表达式要在低优先级操作符处拆分成新行,操作符放在新行之首(以便突出操作符)。
拆分出的新行要进行适当的缩进,使排版整齐,语句可读。
if((very_longer_variable1>=very_longer_variable12)
&&(very_longer_variable3<=very_longer_variable14)
&&(very_longer_variable5<=very_longer_variable16))
{
dosomething();
}
virtualCMatrixCMultiplyMatrix(CMatrixleftMatrix,
CMatrixrightMatrix);
for(very_long_initialization;
very_long_condition;
very_long_update)
{
dosomething();
}
示例2-5长行的拆分
2.6修饰符的位置(1条规则)
【规则2-6-1】将修饰符*和&紧靠变量名,以免引起误解。
例如:
char*name;
int*x,y;/*此处y不会被误解为指针*/
2.7注释(12条规则)
C语言的注释符为“/*…*/”和“//”。
注释通常用于:
(1)版本、版权声明;
(2)函数接口说明,包括参数类型和意义、函数类型和意义等;
(3)重要的数据类型声明、变量、算法、处理、段落等提示。
“//”为行注释。
【规则2-7-1】注释是对代码作用的“提示”,而不是文档。
注释的频度要合适,一般要求占程序总行数的1/5~1/4。
【规则2-7-2】边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。
不再有用的注释要删除。
【规则2-7-3】注释应准确、易懂,防止注释有二义性。
错误的注释不但无益反而有害。
【规则2-7-4】尽量避免在注释中使用缩写,特别是不常用的缩写。
根据维护程序的对象确定使用中文还是使用英文。
【规则2-7-5】注释的位置应与被描述代码相邻,可以放在代码的上方或右方,一般不宜放在下方。
【规则2-7-6】当代码比较长,特别是有多重嵌套时,应当在一些段落的结束处加注释,便于阅读。
【规则2-7-7】尽量不要在语句指令中添加注释。
【规则2-7-8】注释不具备约束使用者行为的能力。
【规则2-7-9】给一行代码添加注释最好使用“//”,比较清楚。
【规则2-7-10】不要使用/**/注释掉大量代码,而要使用#if0条件编译语句
例如:
【规则2-7-11】行末注释最好对齐。
【规则2-7-12】应对包含的头文件进行行末注释。
3.标识符命名(15条规则+1条建议)
共性规则是被大多数程序员采纳的,我们应当在遵循这些共性规则。
命名两个基本原则:
1.含义清晰,不易混淆;
2.不与其它模块、函数的命名空间相冲突。
【规则3-1-1】标识符要清楚、准确、简单而且尽量可发音的英文名字。
例如:
intreturnStatus;
不要把currentValue写成nowValue。
【规则3-1-2】标识符的长度应当符合“min-length&&max-information”(最短并包含信息最多)原则。
单字符的名字也是有用的,常见的如i、j、k、m、n、x、y、z等,它们通常可用作函数内的局部变量。
【规则3-1-3】命名规则尽量与所采用的操作系统或开发工具的风格保持一致。
例如Windows应用程序的标识符通常采用“大小写”混排的方式,如printStudent;而Unix应用程序的标识符通常采用“小写加下划线”的方式,如print_student。
别把这两类风格混在一起用。
【规则3-1-4】尽量选择通用词汇并保持整个软件风格一致。
例如:
使用get、read、fetch、retrieve都能表达“取出”的意思,一旦软件采用哪一个则应贯穿始终。
【规则3-1-5】程序中不要出现仅靠大小写区分的相似的标识符。
例如:
intx,X;/*变量x与X容易混淆*/
voidfoo(inty);/*函数foo与FOO容易混淆*/
voidFOO(floaty);
【规则3-1-6】程序中不要出现标识符完全相同的局部变量和全局变量,尽管可能两者的作用域不同而不会发生语法错误,但会使人误解。
【规则3-1-7】变量的名字应当使用“名词”或者“形容词+名词”。
例如:
floatvalue;
floatnewValue;
【规则3-1-8】用正确的反义词组命名具有互斥意义的变量或相反动作的函数等。
例如:
intMinValue;
intMaxValue;
intMinValue(void);
intMaxValue(void);
【规则3-1-9】变量和参数首字母小写,其后每个英文单词的第一个字母大写,其它小写。
例如:
intrecWidth;
【规则3-1-10】标识布尔型的变量或函数名称一般使用is作为前缀。
例如:
voidisFull();
【规则3-1-11】常量全用大写字母,用下划线分割单词。
constintMAX_LENGTH=100;
【规则3-1-12】静态变量加前缀s_(表示static)。
staticints_initValue;/*静态变量*/
【规则3-1-13】如果需要定义全局变量,则变量加前缀g_(表示global)。
例如:
intg_howStudent;/*全局变量*/
【规则3-1-14】函数名用大写字母开头的单词组合而成。
由多个单词组成的标识符每个单词首字母大写。
其它小写。
例如:
InputStudInfo();//全局函数
【规则3-1-15】一般错误包裹函数名全部大写。
例如:
可以定义成下面的包裹函数
以后调用的话,则可以使用下面的简洁方式:
FILE*pFile=FOPEN("readme.txt","rw++");
【建议3-1-1】尽量避免名字中出现数字编号,如value1、value2等,除非逻辑上的确需要编号。
4.常量(7条规则)
常量是一种标识符,它的值在运行期间恒定不变。
C语言用#define来定义常量。
除了#define之外还可以用const来定义常量。
4.1const与#define的比较(2条规则)
C语言可以用const来定义常量,也可以用#define来定义常量。
但是前者比后者有更多的优点:
(1)const常量有数据类型,而宏常量没有数据类型。
编译器可以对前者进行类型安全检查。
而对后者只进行字符替换,没有类型安全检查,并且在字符替换过程中可能会产生意料不到的错误。
(2)有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。
【规则4-1-1】尽量使用含义直观的常量来表示那些将在程序中多次出现的数字或字符串。
例如:
#defineMAX100//C语言的宏常量
constfloatPI=3.14159;//C语言的const常量
【规则4-1-2】尽量使用const定义常量替代宏定义常量。
4.2常量定义(5条规则)
【规则4-2-1】需要对外公开的常量放在头文件中,不需要对外公开的常量放在定义文件的头部。
为便于管理,可以把不同模块的常量集中存放在一个公共的头文件中。
【规则4-2-2】如果某一常量与其它常量密切相关,则应在定义中包含这种关系,而不应给出一些孤立的值。
例如:
constfloatRADIUS=100;
constfloatDIAMETER=RADIUS*2;
【规则4-2-3】enum中的枚举常量应以大写字母开头或全部大写。
【规则4-2-4】如果宏值多于一项,一定使用括号。
例如:
#defineERROR_DATA_LENGTH10+1
应该这样定义:
#defineERROR_DATA_LENGTH(10+1)
这样使用malloc(5*ERROR_DATA_LENGTH)时,得到是5*(10+1)=55;而上面的定义则得到5*10+1=51。
【规则4-2-5】函数宏的每个参数都要括起来。
例如:
#defineWEEKS_TO_DAYS(w)(w*7)
应该写成:
#defineWEEKS_TO_DAYS(w)((w)*7)
这样在翻译totalDays=WEEKS_TO_DAYS(1+2)时,才能够正确地翻译成:
(1+2)*7;否则将错误地翻译成1+2*7。
5.变量(11条规则)
【规则5-1-1】局部变量在引用之前要进行出初始化或要有明确的值。
【规则5-1-2】如果指针变量知道被初始化为什么地址,则初始化为该地址,否则初始化为NULL。
【规则5-1-3】所有的外部变量声明前都应加上extern关键字。
【规则5-1-4】尽量不要使用一个bit位控制程序流程或标识特定状态。
最好使用多位或枚举类型标识状态。
【规则5-1-5】如果定义数组时全部初始化,则不用给出数组长度。
例如:
intarray[]={1,2,3,4,5};
在需要使用数组长度时,用sizeof(array)/sizeof(array[0])计算得出。
【规则5-1-6】不同文件的全局变量没有固定的初始化顺序,注意使用#include包括的文件都算作同一文件。
【规则5-1-7】尽量避免强制类型转换;如果不得不使用,则尽量使用显式方式。
【规则5-1-8】不要强制指针指向尺寸不同的目标。
例如:
intFunction(constchar*pChar)
{
int*pInt=(constint*)pChar;/*危险操作*/
return(*pInt);
}
【规则5-1-9】尽量少使用无符号类型,其在混合表达式中可能隐式转换造成错误。
【规则5-1-10】尽量少的使用浮点类型,因为浮点数据标识不精确,而且运算速度慢。
【规则5-1-11】尽量少用union类型,因为成员共用内存空间,处理不当容易出错。
6.表达式和基本语句(17条规则+3条建议)
6.1运算符的优先级(1条规则)
【规则6-1-1】避免使用默认的优先级。
如果代码行中的运算符比较多,为了防止产生歧义并提高可读性,应当用括号明确表达式的计算顺序。
例如:
value=(high<<8)|low
if((a|b)&&(a&c))
6.2复合表达式(4条规