3. 标识符命名
3.1 标识符的命名要清晰、明了, 有明确含义, 同时使用完整的单词或大家基本可以理解的缩写, 避免使人 产生误解。
说明: 较短的单词可通过去掉“元音”形成缩写; 较长的单词可取单词的头几个字母形成缩写; 一些单词有大家公 认的缩写。
示例: 如下单词的缩写能够被大家基本认可。
temp可缩写为 tmp; 临时
flag可缩写为 flg; 标志
statistic可缩写为 stat ; 统计
increment可缩写为 inc; 增量
message可缩写为 msg; 消息
3.2 命名中若使用特殊约定或缩写, 则要有注释说明。
说明: 应该在源文件的开始之处, 对文件中所使用的缩写或约定, 特别是特殊的缩写, 进行必要的注释说明。
3.3 自己特有的命名风格, 要自始至终保持一致, 不可来回变化。
说明: 个人的命名风格, 在符合所在项目组或产品组的命名规则的前提下, 才可使用。(即命名规则中没有规定 到的地方才可有个人命名风格)。
3.4 对于变量命名, 禁止取单个字符(如i、j、k... ), 建议除了要有具体含义外, 还能表明其变量类型、数据类 型等, 但i、j、k 作局部循环变量是允许的。
说明: 变量, 尤其是局部变量, 如果用单个字符表示, 很容易敲错(如i写成j), 而编译时又检查不出来, 有可能为 了这个小小的错误而花费大量的查错时间。
示例: 下面所示的局部变量名的定义方法可以借鉴。
int liv_Width
其变量名解释如下:
l 局部变量(Local) (其它: g 全局变量(Global)...)
i 数据类型(Interger)
v 变量(Variable) (其它: c 常量(Const)...)
Width 变量含义
这样可以防止局部变量与全局变量重名。
3.5 命名规范必须与所使用的系统风格保持一致, 并在同一项目中统一, 比如采用UNIX的全小写加下划线的 风格或大小写混排的方式, 不要使用大小写与下划线混排的方式, 用作特殊标识如标识成员变量或全局 变量的m_ 和g_ , 其后加上大小写混排的方式是允许的。
示例: Add_User不允许, add_user、AddUser、m_AddUser允许。
1、除非必要, 不要用数字或较奇怪的字符来定义标识符。
示例: 如下命名, 使人产生疑惑。
#define _EXAMPLE_0_TEST_
#define _EXAMPLE_1_TEST_
void set_sls00( BYTE sls );
应改为有意义的单词命名
#define _EXAMPLE_UNIT_TEST_
#define _EXAMPLE_ASSERT_TEST_
void set_udt_msg_sls( BYTE sls );
2、在同一软件产品内, 应规划好接口部分标识符(变量、结构、函数及常量)的命名, 防止编译、链接时产生 冲突。
说明: 对接口部分的标识符应该有更严格限制, 防止冲突。如可规定接口部分的变量与常量之前加上“模块”标识等。
3、用正确的反义词组命名具有互斥意义的变量或相反动作的函数等。
说明: 下面是一些在软件中常用的反义词组。
========================================================================
add / remove begin / end create / destroy
insert / delete first / last get / release
increment / decrement put / get add / delete
lock / unlock open / close min / max
old / new start / stop next / previous
source / target show / hide send / receive
source / destination cut / paste up / down
===========================================================================
示例:
int min_sum;
int max_sum;
int add_user( BYTE *user_name );
int delete_user( BYTE *user_name );
4、除了编译开关/ 头文件等特殊应用, 应避免使用_EXAMPLE_TEST_ 之类以下划线开始和结尾的定义。
4. 可读性
4.1 注意运算符的优先级, 并用括号明确表达式的操作顺序, 避免使用默认优先级。
说明: 防止阅读程序时产生误解, 防止因默认的优先级与设计思想不符而导致程序出错。
示例: 下列语句中的表达式
word = (high << 8) | low (1)
if ((a | b) && (a & c)) (2)
if ((a | b) < (c & d)) (3)
如果书写为:
high << 8 | low
a | b && a & c
a | b < c & d
由于
high << 8 | low 等价于 ( high << 8) | low
a | b && a & c 等价于 (a | b) && (a & c)
故(1)(2)不会出错, 但语句不易理解, 而
a | b < c & d 等价于 a | (b < c) & d
故(3)造成了判断条件出错。
4.2 避免使用不易理解的数字, 用有意义的标识来替代。涉及物理状态或者含有物理意义的常量, 不应直接 使用数字, 必须用有意义的枚举或宏来代替。
示例: 如下的程序可读性差。
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
}
1、源程序中关系较为紧密的代码应尽可能相邻。
说明: 便于程序阅读和查找。
示例: 以下代码布局不太合理。
rect.length = 10;
char_poi = str;
rect.width = 5;
若按如下形式书写, 可能更清晰一些。
rect.length = 10;
rect.width = 5; // 矩形的长与宽关系较密切, 放在一起。
char_poi = str;
2、不要使用难懂的技巧性很高的语句, 除非很有必要时。
说明: 高技巧语句不等于高效率的程序,实际上程序的效率关键在于算法。
示例: 如下表达式, 考虑不周就可能出问题, 也较难理解。
* stat_poi ++ += 1;
* ++ stat_poi += 1;
应分别改为如下:
*stat_poi += 1;
stat_poi++; // 此二语句功能相当于“ * stat_poi ++ += 1; ”
和
++ stat_poi;
*stat_poi += 1; // 此二语句功能相当于“ * ++ stat_poi += 1; ”