程序风格规范
1、排版
缩进:程序需要缩进的地方统一缩进4个空格。
分界符:应该独占一行,如{ },并且对齐在同一列,与引用他们的语句左对齐,在{}中的语句应该统一缩进4个空格。如:
for( ; ; )
{
………// 语句
}
较长的语句: >80字符的语句及循环和判断中较长的表达式要分成多行书写,长表达式要在低优先级操作符处划分新行,操作符放在新行之首,划分出的新行要进行适当的缩进,使排版整齐,语句可读。
短语句及循环、判断、等:每一条语句占用一行,不能将几个短语句放在同一行,循环或判断等语句独占一行。
例:
i = 0; j = 0; //错误
i = 0;
j = 0;
if(a<b) return a;//错误
if(a<b)
{
return a; //正确
}
对齐只使用空格键,不使用TAB键
运算符的使用:运算符在使用的时候都应该和变量之间用空格隔开,进行非对等操作时,如果是关系密切的立即操作符(如->),后不应加空格提高语句可读性。
示例:
(1)逗号、分号只在后面加空格。
int a, b, c;
(2)比较操作符, 赋值操作符"="、 "+=",算术操作符"+"、 "%",逻辑操作符"&&"、"&",位域操作符"<<"、 "^"等双目操作符的前后加空格。
if (current_time >=MAX_TIME_VALUE)
a = b + c;
a *= 2;
a = b ^ 2;
(3)"!"、"~"、 "++"、"--"、 "&"(地址运算符)等单目操作符前后不加空格。*p = 'a'; // 内容操作"*"与内容之间
flag = !isEmpty; // 非操作"!"与内容之间
p = &mem; // 地址操作"&"与内容之间
i++; //"++","--"与内容之间
(4)"->"、"."前后不加空格。
p->id = pid; //"->"指针前后不加空格
(5) if、 for、 while、 switch 等与后面的括号间应加空格,使 if 等关键字更为突出、明显。
if (a >= b && c> d)
代码块的间隔:函数与函数之间,类与类之间,代码块与代码块之间,头文件或包调用与代码之间都应该用单独一行隔开。
2、注释
注释内容要求:
源程序有效注释必须在20%以上,并且要有程序说明文件,必须列出:版权说明、版本号、生成日期、作者、主要功能、编程思想、修改日志等。还要列出一个函数及变量菜单,说明基本变量及函数的作用、返回值。
注释风格要求:
边写代码边注释,修改时要修改相应的注释,删除多余的注释,避免在注释中使用缩进,同一个函数或类中的注释应该尽可能对其,使程序整体美观。
注释应与其描述的代码相近,注释应放在其上方或右方,不能放在下面,放在上面应与上面的代码用空行隔开。注释与所描述内容进行同样的缩排。
例:
voidexample_fun( void )
{
/* code onecomments */
CodeBlock One
/* code twocomments */
CodeBlock Two
}
全局变量:全局变量要有较详细的注释,包括对其功能、取值范围、哪些函数或过程存取它以及存取时注意事项等的说明。
必须加注释:对变量的定义和分支语句(条件分支、循环语句等)必须编写注释,对于switch语句下的case语句,如果因为特殊情况需要处理完一个case后进入下一个case处理,必须在该case语句处理完、下一个case语句前加上明确的注释。
不提倡的注释:在一行代码或表达式的中间插入注释。
通过对函数或过程、变量、结构等正确的命名以及合理地组织代码的结构,使代码成为自注释的。在代码的功能、意图层次上进行注释,提供有用、额外的信息。在程序块的结束行右方加注释标记,以表明某程序块的结束。
注释符的使用:注释符尽量使用统一的,使用“/*………*/”。
3、标识符命名
命名:标识符的命名要清晰、明了,有明确含义,同时使用完整的单词或大家基本可以理解的缩写,避免使人产生误解。
示例:如下单词的缩写能够被大家基本认可。
temp 可缩写为 tmp ;
flag 可缩写为 flg ;
statistic 可缩写为 stat;
increment 可缩写为 inc ;
message 可缩写为 msg ;
命名中若使用特殊约定或缩写,则要有注释说明。自己特有的命名风格,要自始至终保持一致,不可来回变化。
变量名命名:禁止取单个字符(如i、 j、 k...),建议除了要有具体含义外,还能表明其变量类型、数据类型等,但i、 j、 k作局部循环变量是允许的。
命名规范必须与所使用的系统风格保持一致,并在同一项目中统一,比如采用UNIX的全小写加下划线的风格或大小写混排的方式,不要使用大小写与下划线混排的方式,用作特殊标识如标识成员变量或全局变量的m_和g_,其后加上大小写混排的方式是允许的。
除非必要,不要用数字或较奇怪的字符来定义标识符。
在同一软件产品内,应规划好接口部分标识符(变量、结构、函数及常量)的命名,防止编译、链接时产生冲突。
4、可读性
注意运算符的优先级,并用括号明确表达式的操作顺序,避免使用默认优先级。
示例:下列语句中的表达式。
word = (high<< 8) | low (1)
if ((a| b) && (a & c)) (2)
if ((a| b) < (c & d)) (3)
避免使用不易理解的数字,用有意义的标识来替代。涉及物理状态或者含有物理意义的常量,不应直接使用数字,必须用有意义的枚举或宏来代替。
源程序中关系较为紧密的代码应尽可能相邻。
rect.length = 10;
rect.width = 5; // 矩形的长与宽关系较密切,放在一起。
char_poi = str;
不要使用难懂的技巧性很高的语句,除非很有必要时。
5、函数、过程
对所调用函数的错误返回码要仔细、全面地处理。明确函数功能,精确(而不是近似)地实现函数设计。编写可重入函数时,应注意局部变量的使用。编写可重入函数时,若使用全局变量,则应通过关中断、信号量(即P、 V操作)等手段对其加以保护。
在同一项目组应明确规定对接口函数参数的合法性检查应由函数的调用者负责还是由接口函数本身负责,缺省是由函数调用者负责。
防止将函数的参数作为工作变量。
void sum_data( unsignedint num, int *data, int *sum )
{
unsigned intcount ;
int sum_temp;
sum_temp = 0;
for (count = 0;count < num; count ++)
{
sum_temp +=data[count];
}
*sum = sum_temp;
}
函数编写要求:函数的规模尽量限制在200行以内。一个函数仅完成一件功能。为简单功能编写函数。不要设计多用途面面俱到的函数。函数的功能应该是可以预测的,也就是只要输入数据相同就应产生同样的输出。尽量不要编写依赖于其他函数内部实现的函数。
避免设计多参数函数,不使用的参数从接口中去掉。非调度函数应减少或防止控制参数,尽量只使用数据参数。
检查函数所有参数输入的有效性。
检查函数所有非参数输入的有效性,如数据文件、公共变量等。
函数名应准确描述函数的功能。
函数的返回值要清楚、明了,让使用者不容易忽视错误情况。
在调用函数填写参数时,应尽量减少没有必要的默认数据类型转换或强制数据类型转换。
功能不明确较小的函数,特别是仅有一个上级函数调用它时,应考虑把它合并到上级函数中,而不必单独存在。
改进模块中函数的结构,降低函数间的耦合度,并提高函数的独立性以及代码可读性、效率和可维护性。优化函数结构时,要遵守以下原则:
( 1)不能影响模块功能的实现。
( 2)仔细考查模块或函数出错处理及模块的性能要求并进行完善。
( 3)通过分解或合并函数来改进软件结构。
( 4)考查函数的规模,过大的要进行分解。
( 5)降低函数间接口的复杂度。
( 6)不同层次的函数调用要有较合理的扇入、扇出。
( 7)函数功能应可预测。
( 8)提高函数内聚。(单一功能的函数内聚最高)
说明:对初步划分后的函数结构应进行改进、优化,使之更为合理。
6、变量、结构
公共变量:去掉没有必要的公共变量,仔细定义并明确公共变量的含义、作用、取值范围及公共变量间的关系。明确公共变量与操作此公共变量的函数或过程的关系,如访问、修改及创建等。
当向公共变量传递数据时,要十分小心,防止赋与不合理的值或越界等现象发生。防止局部变量与公共变量同名。严禁使用未经初始化的变量作为右值。
构造仅有一个模块或函数可以修改、创建,而其余有关模块或函数只访问的公共变量,防止多个不同模块或函数都可以修改、创建同一公共变量的现象。
使用严格形式定义的、可移植的数据类型,尽量不要使用与具体硬件或软件环境关系密切的变量。
结构:
结构的功能要单一,是针对一种事务的抽象。不要设计面面俱到、非常灵活的数据结构。不同结构间的关系不要过于复杂。结构中元素的个数应适中。若结构中元素个数过多可考虑依据某种原则把元素组成不同的子结构,以减少原结构中元素的个数。
仔细设计结构中元素的布局与排列顺序,使结构容易理解、节省占用空间,并减少引起误用现象。
强制转换:编程时,要注意数据类型的强制转换。对编译系统默认的数据类型转换,也要有充分的认识。尽量减少没有必要的数据类型默认转换与强制转换。合理地设计数据并使用自定义数据类型,避免数据间进行不必要的类型转换。
自定义数据类型:对自定义数据类型进行恰当命名,使它成为自描述性的,以提高代码可读性。注意其命名方式在同一产品中的统一。