目录
1 排版
1-1 缩进
1-2 独立说明加空行
1-3 字符 80+ 多行书写
1-4 较长语句进行划分
1-5 内嵌语句独占且加括号
1-6 空格对齐
1-7 操作符与空格
2 注释
2-1 说明文件
2-2 源文件
2-3 函数
2-4 数据结构
2-5 全局变量
2-6 相同缩排
2-7 代码接注释隔行
2-8 结束行右方注释
2-9 统一注释格式
3 标识符命名
3-1 缩写去“元音”
3-2 说明特殊内容
3-3 禁止单字符
3-4 成员 m、全局 g
3-5 反义词组成
4 可读性
4-1 标识替代数字
4-2 相邻紧密的代码
程序块要采用缩进风格编写,缩进的空格数为 4 个
相对独立的程序块之间、变量说明之后必须加空行
示例:
if (!valid_ni(ni))
{
... // program code
}
repssn_ind = ssn_data[index].repssn_index;
repssn_ni = ssn_data[index].ni;
较长语句(>80字符)分多行书写,长表达式要在低优先级操作符处划分新行,操作符放在新行之首,划分出的新行要适当缩进
perm_count_msg.head.len = NO7_TO_STAT_PERM_COUNT_LEN
+ STAT_SIZE_PER_FRAM * sizeof( _UL );
act_task_table[frame_id * STAT_TASK_CHECK_NUMBER + index].occupied
= stat_poi[index].occupied;
report_or_not_flag = ((taskno < MAX_ACT_TASK_NUMBER)
&& (n7stat_stat_item_valid (stat_item))
&& (act_task_table[taskno].result_data != 0));
循环、判断等语句中若有较长的表达式或语句,要进行适应划分,长表达式要在低优先级操作符处划分新行,操作符放在新行之首
示例:
if ((taskno < max_act_task_number)
&& (n7stat_stat_item_valid (stat_item)))
{
... // program code
}
for (i = 0, j = 0; (i < BufferKeyword[word_index].word_length)
&& (j < NewKeyword.word_length); i++, j++)
{
... // program code
}
for (i = 0, j = 0;
(i < first_word_length) && (j < second_word_length);
i++, j++)
{
... // program code
}
if、for、do、while、case、switch、default 等语句自占一行,且 if、for、do、while 等的执行语句部分要加括号{ }
if (pUserCR == NULL)
{
return;
}
对齐只使用空格键,不使用TAB键。
// 说明:以免用不同的编辑器阅读程序时,因 TAB 键所设置的空格数目不同而造成程序布局
// 不整齐,不要使用 BC 作为编辑器合版本,因为 BC 会自动将 8 个空格变为一个 TAB 键,
// 因此使用 BC 合入的版本大多会将缩进变乱。
在两个以上关键字、变量、常量对等操作时,之间的操作符之前、之后或前后加空格;非对等操作时,关系密切的立即操作符(如->)后不加空格
(1)"!"、"~"、"++"、"--"、"&"(地址运算符)等单目操作符前后不加空格。
*p = 'a'; // 内容操作"*"与内容之间
flag = !isEmpty; // 非操作"!"与内容之间
p = &mem; // 地址操作"&" 与内容之间
i++; // "++","--"与内容之间
(2)"->"、"."前后不加空格。
p->id = pid; // "->"指针前后不加空格
(3) if、for、while、switch 等与后面的括号间应加空格,使 if 等关键字更为突出、明显。
if (a >= b && c > d)
说明性文件(.h文件、.inc文件、.def文件、编译说明文件.cfg等)头部应注释,必须列出:版权说明、版本号、生成日期、作者、内容、功能、与其它文件的关系、修改日志等,还应有函数功能简要说明。
/***************************************************
Copyright (C), Your Company
File name: // 文件名
Author: Version: Date: // 作者、版本及完成日期
Description: // 用于详细说明此程序文件完成的主要功能,与其他模块
// 或函数的接口,输出值、取值范围、含义及参数间的控
// 制、顺序、独立或依赖等关系
Others: // 其它内容的说明
Function List: // 主要函数列表,每条记录应包括函数名及功能简要说明
1. ....
History: // 修改历史记录列表,每条修改记录应包括修改日期、修改
// 者及修改内容简述
1. Date:
Author:
Modification:
2. ...
***************************************************/
源文件头部应注释,列出:版权说明、版本号、生成日期、作者、模块目的/功能、主要函数及其功能、修改日志等。
/************************************************************
Copyright (C), 1988-1999, Huawei Tech. Co., Ltd.
FileName: test.cpp
Author: Version : Date:
Description: // 模块描述
Version: // 版本信息
Function List: // 主要函数及其功能
1. -------
History: // 历史修改记录
函数头部应注释,列出:函数的目的/功能、输入参数、输出参数、返回值、调用关系(函数、表)等。
/*************************************************
Function: // 函数名称
Description: // 函数功能、性能等的描述
Calls: // 被本函数调用的函数清单
Called By: // 调用本函数的函数清单
Table Accessed: // 被访问的表(此项仅对于牵扯到数据库操作的程序)
Table Updated: // 被修改的表(此项仅对于牵扯到数据库操作的程序)
Input: // 输入参数说明,包括每个参数的作
// 用、取值说明及参数间关系。
Output: // 对输出参数的说明。
Return: // 函数返回值的说明
Others: // 其它说明
*************************************************/
数据结构声明(数组、结构、类、枚举等),如果其命名不充分自注释则须加以注释。对数据结构的注释应放其上方;结构中每个域的注释放右方
示例:可按如下形式说明枚举/数据/联合结构。
/* sccp interface with sccp user primitive message name */
enum SCCP_USER_PRIMITIVE
{
N_UNITDATA_IND, /* sccp notify sccp user unit data come */
N_NOTICE_IND, /* sccp notify user the No.7 network can not */
/* transmission this message */
N_UNITDATA_REQ, /* sccp user's unit data transmission request*/
};
全局变量要有详细注释,包括对其功能、取值范围、哪些函数或过程存取它以及存取时注意事项等的说明
/* The ErrorCode when SCCP translate */
/* Global Title failure, as follows */ // 变量作用、含义
/* 0 - SUCCESS 1 - GT Table error */
/* 2 - GT error Others - no use */ // 变量取值范围
/* only function SCCPTranslate() in */
/* this modual can modify it, and other */
/* module can visit it through call */
/* the function GetGTTransErrorCode() */ // 使用方法
BYTE g_GTTranErrorCode;
注释与所描述内容进行同样的缩排。
void example_fun( void )
{
/* code one comments */
CodeBlock One
/* code two comments */
CodeBlock Two
}
将注释与其上面的代码用空行隔开
/* code one comments */
program code one
/* code two comments */
program code two
在程序块的结束行右方加注释标记,以表明某程序块的结束
if (...)
{
// program code
while (index < MAX_INDEX)
{
// program code
} /* end of while (index < MAX_INDEX) */ // 指明该条 while 语句结束
} /* end of if (...)*/ // 指明是哪条 if 语句结束
注释格式尽量统一,建议使用 /* …… */
较短单词通过去掉“元音”形成缩写;较长单词取头几个字母形成缩写;一些有公认缩写
temp 可缩写为 tmp ;
flag 可缩写为 flg ;
statistic 可缩写为 stat ;
increment 可缩写为 inc ;
message 可缩写为 msg ;
命名中若使用特殊约定或缩写,则要有注释说明
禁止取单字符(i、j、k),有具体含义外,还能表明变量类型、数据类型等,可作局部循环变量
int liv_Width;
/*
其变量名解释如下:
l 局部变量(Local) (其它:g 全局变量(Global)...)
i 数据类型(Interger)
v 变量(Variable) (其它:c 常量(Const)...)
Width 变量含义
*/
不用大小写与下划线混排,用作特殊标识如标识成员或全局变量的 m_ 和 g_ ,后加大小写混排的方式
示例: Add_User 不允许,add_user、AddUser、m_AddUser 允许。
用正确的反义词组命名具有互斥意义的变量或相反动作的函数等
/*
add / move create / destory insert / delete
add / delete first / last increment / decrement
put / get get / release old / new
start / stop begin / end open / close
min / max lock / unlock next / previous
cut / paste send / receive show / hide
up / down source / target source / destination
*/
避免用不易理解的数字,用标识替代。涉及物理状态或含有物理意义的常量,用有意义的枚举或宏代替
示例:如下的程序可读性差。
if (Trunk[index].trunk_state == 0)
{
Trunk[index].trunk_state = 1;
... // program code
}
应改为如下形式。
#define TRUNK_IDLE 0
#define TRUNK_BUSY 1
if (Trunk[index].trunk_state == TRUNK_IDLE)
{
Trunk[index].trunk_state = TRUNK_BUSY;
... // program code
}
源程序中关系较为紧密的代码应尽可能相邻
rect.length = 10;
rect.width = 5; // 矩形的长与宽关系较密切,放在一起。
char_poi = str;