代码原则二

【规则4-1】标识符要采用英文单词或其组合,便于记忆和阅读,切忌使用汉语拼音来命名。
【规则4-2】标识符只能由26个英文字母,10个数字,及下划线的一个子集来组成,并严格禁止使用连续的下划线,下划线也不能出现在标识符头或结尾(预编译开关除外)。
【规则4-3】标识符的命名应当符合“min-length && max-information”原则。


Delay
Dly
Device
Dev
Disable
Dis
Display
Disp
Enable
En
Error
Err
Function
Fnct
Hexadecimal
Hex
High Priority Task
HPT
I/O System
IOS
Initialize
Init
Mailbox
Mbox
Manager
Mgr
Manual
Man
Maximum
Max
Message
Msg
Minimum
Min
Multiplex
Mux
Operating System
OS
Overflow
Ovf
Parameter
Param
Pointer
Ptr
Previous
Prev
Priority
Prio
Read
Rd
Ready
Rdy
Register
Reg
Schedule
Sched
Semaphore
Sem
Stack
Stk
Synchronize
Sync
Timer
Tmr
Trigger
Trig
Write
Wr
【规则4-4】程序中不要出现仅靠大小写区分的相似的标识符。
【规则4-5】用正确的反义词组命名具有互斥意义的变量或相反动作的函数等。
说明:下面是一些在软件中常用的反义词组。 


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
正例:如 DISP_BUF_SIZE、MIN_VALUE、MAX_VALUE 等等。
说明:变量,尤其是局部变量,如果用单个字符表示,很容易出错(如l误写成1),而编译时又检查不出,则有可能增加排错时间。过长的变量名会增加工作量,会使程序的逻辑流程变得模糊,给修改带来困难,所以应当选择精炼的意义明确的名字,才能简化程序语句,改善对程序功能的理解。
说明:尽管局部变量和全局变量的作用域不同而不会发生语法错误,但容易使人误解。
说明:变量活动范围前缀规范如下:
g_ : 全局变量
s_ : 模块内静态变量
空 : 局部变量不加范围前缀
【规则4-6】宏、常量名都要使用大写字母, 用下划线 ’_’ 分割单词。预编译开关的定义使用下划线 ’_’ 开始。
【规则4-7】变量名长度应小于31个字符,以保持与ANSI C标准一致。不得取单个字符(如i、j、k等),但是局部循环变量除外。
【规则4-8】程序中局部变量不要与全局变量重名。
【规则4-9】使用一致的前缀来区分变量的活动范围。
【规则4-10】使用一致的小写类型指示符作为前缀来区分变量的类型。
说明:常用变量类型前缀列表如下:
i : int
f : float
d : double
c : char
uc : unsigned char 或 BYTE
l : long
p : pointer
b : BOOL
h : HANDLE
w : unsigned short 或 WORD
dw : DWORD或 unsigned long
a : 数组,array of TYPE
str : 字符串
t : 结构类型
o : 对象
以上前缀可以进一步组合成新的类型,在进行组合时,数组和指针类型的前缀指示符必须放在变量类型前缀的首位。
说明:各种前缀字符可能组合使用,在这种情况下,各前缀顺序为:变量活动范围前缀、变量类型前缀。
正例:
float g_fValue; //类型为浮点数的全局变量
char *pcOldChar; //类型为字符指针的局部变量
说明:函数名力求清晰、明了,通过函数名就能够判断函数的主要处理功能。函数名中不同意义字段之间不要用下划线连接,而要把每个字段的首字母大写以示区分。函数命名采用大小写字母结合的形式,但专有名词不受限制。
【规则4-14】事件名由前缀EV_ 开头。
【规则4-11】完整的变量名应由前缀+变量名主体组成,变量名的主体应当使用“名词”或者“形容词+名词”,且首字母必须大写。
【规则4-12】函数名用大写字母开头的单词组合而成,且应当使用“动词”或者“动词+名词”(动宾词组)。
【规则4-13】结构名由前缀T_ 开头,联合名由前缀U_ 开头。
【规则4-15】类名采用大小写结合的方法。在构成类名的单词之间不用下划线,类名在开头加上C,类的成员变量统一在前面加m_ 前缀。


void Object::SetValue(int iWidth, int iHeight)
{
m_iWidth = iWidth;
m_iHeight = iHeight;
}
【建议4-1】尽量避免名字中出现数字编号,如Value1、Value2等,除非逻辑上的确需要编号。
【建议4-2】标识符前最好不加项目、产品、部门的标识和修饰。
说明:这样做的目的是为了代码的可重用性。


5. 变量、常量与类型
变量、常量和数据类型是程序编写的基础,它们的正确使用直接关系到程序设计的成败,变量包括全局变量、局部变量和静态变量,常量包括数据常量、常量类型数据和指针常量,类型包括系统的数据类型和自定义数据类型。本章主要说明变量、常量与类型使用时必须遵循的规则和一些需注意的建议,关于它们的命名,参见命名规则。
5.1 变量与常量
【规则5-1-1】定义全局变量时必须仔细分析,明确其含义、作用、取值范围及与其它全局变量间的关系。
说明:全局变量关系到程序的结构框架,对于全局变量的理解关系到对整个程序能否正确理解,所以在对全局变量声明的同时,应对其含义、作用及取值范围进行详细地注释说明,若有必要还应说明与其它变量的关系。
【规则5-1-2】明确全局变量与操作此全局变量的函数或过程的关系。
说明:全局变量与函数的关系包括:创建、修改及访问。明确过程操作变量的关系后,将有利于程序的进一步优化、单元测试、系统联调以及代码维护等。这种关系的说明可在注释或文档中描述。
【规则5-1-3】一个变量有且只有一个功能,不能把一个变量用作多种用途。
说明:一个变量只用来表示一个特定功能,不能把一个变量作多种用途,即同一变量取值不同时,其代表的意义也不同。
正例:
WORD DelRelTimeQue(T_TCB *ptTcb )
{
WORD wValue;
WORD wLocate;
wLocate = 3;
wValue = DeleteFromQue(wLocate);


}
反例:
WORD DelRelTimeQue(T_TCB *ptTcb)
{
WORD wLocate;
wLocate = 3;
wLocate = DeleteFromQue(wLocate); // wLocate 具有两种功能。
return wLocate;
}
【规则5-1-4】循环语句与判断语句中,不允许对其它变量进行计算与赋值。
说明:循环语句只完成循环控制功能,if语句只完成逻辑判断功能,不能完成计算赋值功能。
正例:
do
{
[处理语句]
cInput = GetChar();
} while (cInput == 0);
反例:
do
{
[处理语句]
} while (cInput = GetChar());
【规则5-1-5】宏定义中如果包含表达式或变量,表达式和变量必须用小括号括起来。
说明:在宏定义中,对表达式和变量使用括号,可以避免可能发生的计算错误。
正例:
#define HANDLE(A, B) (( A ) / ( B ))
反例:
#define HANDLE(A, B) (A / B)


【规则5-1-6】尽量使用const说明常量数据,对于宏定义的常数,必须指出其类型。
正例:
const int MAX_COUNT = 1000;
#define MAX_COUNT (int)1000
反例:
#define MAX_COUNT 1000
〖建议5-1-1〗尽量构造仅有一个模块或函数可以修改、创建,而其余有关模块或函数只访问的全局变量。
说明:减少全局变量操作引起的错误。
正例:在源文件中,可按如下注释形式说明。
T_Student *g_ptStudent;
变量 关系 函数
g_pStudent 创建 SystemInit(void)
修改 无
访问 StatScore(const T_Student *ptStudent)
PrintRec(const T_Student *ptStudent)
〖建议5-1-2〗对于全局变量通过统一的函数访问。
说明:可以避免访问全局变量时引起系统错误。
正例:
T_Student g_tStudent;
T_Student GetStudentValue(void)
{
T_Student tStudentValue;
[获取g_tStudent的访问权]
tStudentValue = g_tStudent;
[释放g_tStudent的访问权]
return tStudentValue;
}
BYTE SetStudentValue(const T_Student *ptStudentValue)
{


BYTE ucIfSuccess;
ucIfSuccess = 0;
[获取g_tStudent的访问权]
g_tStudent = *ptStudentValue ;
[释放g_tStudent的访问权]
return ucIfSuccess;
}
5.2 类型
【规则5-2-1】结构和联合必须被类型化。
正例:
typedef struct {
char acName[NAME_SIZE];
WORD wScore;
}T_Student;
T_Student *ptStudent;
反例:
struct student{
char acName[NAME_SIZE];
WORD wScore;
} *ptStudent;
〖建议5-2-1〗使用严格形式定义的、可移植的数据类型,尽量不要使用与具体硬件或软件环境关系密切的变量。
说明:使用统一的自定义数据类型,有利于程序的移植。
自定义数据类型
类型说明
类型定义(以Win32为例)
VOID
空类型
void
BOOLEAN
逻辑类型 (TRUE或FALSE)
unsigned char
BYTE/ UCHAR
无符号 8 位整数
unsigned char
CHAR
有符号 8 位整数
signed char
WORD16/ WORD
无符号 16 位整数
unsigned short
SWORD16
有符号 16 位整数


WORD32/DWORD
无符号 32 位整数
signed int
SWORD32
有符号 32 位整数
unsigned int
FP32
32 位单精度符点数
float
FP64
64 位双精度符点数
double
〖建议5-2-2〗结构的功能要单一,是针对一种事务的抽象,不要设计面面俱到、非常灵活的数据结构。
说明:设计结构时应力争使结构代表一种现实事务的抽象,而不是同时代表多种。结构中的各元素应代表同一事务的不同侧面,而不应把描述没有关系或关系很弱的不同事务的元素放到同一结构中。
正例:
typedef struct TeacherStruct
{
BYTE aucName[8];
BYTE ucSex;
}T_Teacher;
typedef struct StudentStruct
{
BYTE ucName[8];
BYTE ucAge;
BYTE ucSex;
WORD wTeacherInd;
}T_Student;
反例:
如下结构不太清晰、合理。
typedef struct StudentStruct
{
BYTE aucName[8];
BYTE ucAge;
BYTE ucSex;
BYTE aucTeacherName[8];
BYTE ucTeacherSex;
}T_Student;
〖建议5-2-3〗不同结构间的关系要尽量简单,若两个结构间关系较复杂、密切,那么应合为一个结构。 


说明:两个结构关系复杂时,它们可能反映的是一个事物的不同属性。
由于两个结构都是描述同一事物的,那么不如合成一个结构。
正例:
typedef struct PersonStruct
{
BYTE aucName[8];
BYTE aucAddr[40];
BYTE ucSex;
BYTE aucCity[15];
BYTE ucTel;
}T_Person;
反例:如下两个结构的构造不合理。
typedef struct PersonOneStruct
{
BYTE aucName[8];
BYTE aucAddr[40];
BYTE ucSex;
BYTE ucCity[15];
}T_PersonOne;
typedef struct PersonTwoStruct
{
BYTE aucName[8];
BYTE aucAddr[40];
BYTE ucTel;
}T_PersonTwo;
〖建议5-2-4〗结构中元素的个数应适中。若结构中元素个数过多可考虑依据某种原则把元素组成不同的子结构,以减少原结构中元素的个数。
说明:增加结构的可理解性、可操作性和可维护性。
正例:假如认为如上的_PERSON结构元素过多,那么可如下对之划分。
typedef struct PersonBaseInfoStruct
{
BYTE aucName[8];
BYTE ucAge;
BYTE ucSex;
}T_PersonBaseInfo;
typedef struct PersonAddressStruct


{
BYTE aucAddr[40];
BYTE aucCity[15];
BYTE ucTel;
}T_PersonAddress;
typedef struct PersonStruct
{
T_PersonBaseInfo tPersonBase;
T_PersonAddress tPersonAddr;
}T_Person;
〖建议5-2-5〗仔细设计结构中元素的布局与排列顺序,使结构容易理解、节省占用空间,并减少引起误用现象,对于结构中未用的位明确地给予保留。
说明:合理排列结构中元素顺序,可节省空间并增加可理解性。
正例:如下形式,不仅可节省字节空间,可读性也变好了。
typedef struct ExampleStruct
{
BYTE ucValid: 1;
BYTE ucSetFlg: 1;
BYTE ucOther: 6; // 保留位
T_Person tPerson;
}T_Example;
反例:如下结构中的位域排列,将占较大空间,可读性也稍差。
typedef struct ExampleStruct
{
BYTE ucValid: 1;
T_Person tPerson;
BYTE ucSetFlg: 1;
}T_Example;
〖建议5-2-6〗结构的设计要尽量考虑向前兼容和以后的版本升级,并为某些未来可能的应用保留余地(如预留一些空间等)。
说明:软件向前兼容的特性,是软件产品是否成功的重要标志之一。如果要想使产品具有较好的前向兼容,那么在产品设计之初就应为以后版本升级保留一定余地,并且在产品升级时必须考虑前一版本的各种特性。


〖建议5-2-7〗注意具体语言及编译器处理不同数据类型的原则及有关细节。
说明:如在C语言中,static局部变量将在内存“数据区”中生成,而非stat局部变量将在“堆栈”中生成。这些细节对程序质量的保证非常重要。
〖建议5-2-8〗合理地设计数据并使用自定义数据类型,尽量减少没有必要的数据类型默认转换与强制转换。
〖建议5-2-9〗当声明用于分布式环境或不同CPU间通信环境的数据结构时,必须考虑机器的字节顺序、使用的位域及字节对齐等问题 。
说明:比如Intel CPU与68360 CPU,在处理位域及整数时,其在内存存放的“顺序”,正好相反。
正例:假如有如下短整数及结构。
WORD wExam;
typedef struct ExamBitStruct
{ /* Intel 68360 */
WORD wA1: 1; /* bit 0 2 */
WORD wA2: 1; /* bit 1 1 */
WORD wA3: 1; /* bit 2 0 */
WORD wOther: 13;
}T_ExamBit;
如下是Intel CPU生成短整数及位域的方式。
内存: 0 1 2 ... (从低到高,以字节为单位)
wExam wExam低字节 wExam高字节
内存: 0 bit 1 bit 2 bit ... (字节的各“位”)
T_ExamBit A1 A2 A3
如下是68360 CPU生成短整数及位域的方式。
内存: 0 1 2 ... (从低到高,以字节为单位)
wExam wExam高字节 wExam低字节
内存: 0 bit 1 bit 2 bit ... (字节的各“位”)
T_ExamBit A3 A2 A1
说明:在对齐方式下,CPU的运行效率要快得多。
正例:如下图,当一个long型数(如图中long1)在内存中的位置正好与内存的字边界对齐时,CPU存取这个数只需访问一次内存,而当一个long型数(如图中的long2)


在内存中的位置跨越了字边界时,CPU存取这个数就需要多次访问内存,如i960cx访问这样的数需读内存三次(一个BYTE、一个SHORT、一个BYTE,由CPU的微代码执行,对软件透明),所有对齐方式下CPU的运行效率明显快多了。
1 8 16 24 32
--------- ---------- --------- --------
| long1 | long1 | long1 | long1 |
--------- ---------- -------- ---------
| | | | long2 |
--------- ---------- -------- ---------
| long2 | long2 | long2 | |
--------- ---------- -------- ---------
| ....


6. 表达式与语句
表达式是语句的一部分,它们是不可分割的。表达式和语句虽然看起来比较简单,但使用时隐患比较多。本章归纳了正确使用表达式和if、for、while、goto、switch等基本语句的一些规则与建议。在写表达式和语句的时候要注意运算符的优先级,C/C++语言的运算符有数十个,运算符的优先级与结合律如表6-1所示。注意一元运算符 + - * 的优先级高于对应的二元运算符。
表6-1 运算符的优先级与结合律
优先级
运算符
结合律
( ) [ ] -> .
从左至右
! ~ ++ -- (类型) sizeof
+ - * &
从右至左
* / %
从左至右
+ -
从左至右
<< >>
从左至右
< <= > >=
从左至右
== !=
从左至右
&
从左至右
^
从左至右
|
从左至右
&&
从左至右
||
从右至左
?:
从右至左






= += -= *= /= %= &= ^=
|= <<= >>=
从左至右
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值