应改为如下形式。
#define TRUNK_IDLE 0 #define TRUNK_BUSY 1
if (Trunk[index].trunk_state == TRUNK_IDLE) {
Trunk[index].trunk_state = TRUNK_BUSY; ... // program code }
规则4-3:不要使用难懂的技巧性很高的语句,除非很有必要时。
说明:高技巧语句不等于高效率的程序,实际上程序的效率关键在于算法。 示例:如下表达式,考虑不周就可能出问题,也较难理解。
* stat_poi ++ += 1;
* ++ stat_poi += 1;
应分别改为如下。 *stat_poi += 1;
stat_poi++; // 此二语句功能相当于“ * stat_poi ++ += 1; ”
++ stat_poi;
*stat_poi += 1; // 此二语句功能相当于“ * ++ stat_poi += 1; ”
第五章 变量、结构
建议5-1:尽量少使用全局变量,尽量去掉没必要的公共变量。
说明:公共变量是增大模块间耦合的原因之一,故应减少没必要的公共变量以降低模块间的耦合度。
规则5-1:变量,特别是指针变量,被创建之后应当及时把它们初始化,以防止把未被初始化的变量当成右值使用。
说明:在C/C++中引用未经赋值的指针,经常会引起系统崩溃。
建议5-2:仔细设计结构中元素的布局与排列顺序,使结构容易理解、节省占用空间,并减少引起误用现象。
说明:合理排列结构中元素顺序,可节省空间并增加可理解性。 示例:如下结构中的位域排列,将占较大空间,可读性也稍差。
typedef struct EXAMPLE_STRU {
unsigned int valid: 1; PERSON person;
unsigned int set_flg: 1; } EXAMPLE;
若改成如下形式,不仅可节省1字节空间,可读性也变好了。 typedef struct EXAMPLE_STRU {
unsigned int valid: 1; unsigned int set_flg: 1; PERSON person ; } EXAMPLE;
建议5-3:留心具体语言及编译器处理不同数据类型的原则及有关细节。
说明:如在C语言中,static局部变量将在内存“数据区”中生成,而非static局部
变量将在“堆栈”中生成。这些细节对程序质量的保证非常重要。
建议5-4:尽量减少没有必要的数据类型默认转换与强制转换。
说明:当进行数据类型强制转换时,其数据的意义、转换后的取值等都有可能发生变化,而这些细节若考虑不周,就很有可能留下隐患。
规则5-2:当声明用于分布式环境或不同CPU间通信环境的数据结构时,必须考虑机器的字节顺序、使用的位域及字节对齐等问题 。 说明:
1. 在Intel CPU与SPARC CPU,在处理位域及整数时,其在内存存放的“顺序”正好
相反。
2. 在对齐方式下,CPU的运行效率要快一些 示例:
1. 字节顺序
假如有如下短整数及结构。 unsigned short int exam; typedef struct EXAM_BIT_STRU
{ /* Intel 68360 */ unsigned int A1: 1; /* bit 0 7 */ unsigned int A2: 1; /* bit 1 6 */ unsigned int A3: 1; /* bit 2 5 */ } EXAM_BIT;
如下是Intel CPU生成短整数及位域的方式。
内存: 0 1 2 ... (从低到高,以字节为单位) exam exam低字节 exam高字节
内存: 0 bit 1 bit 2 bit ... (字节的各“位”) EXAM_BIT A1 A2 A3
如下是SPARC CPU生成短整数及位域的方式。
内存: 0 1 2 ... (从低到高,以字节为单位)
exam exam高字节 exam低字节
内存: 7 bit 6 bit 5 bit ... (字节的各“位”) EXAM_BIT A1 A2 A3 2. 对齐
如下图,当一个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-1:调用函数要检查所有可能的返回情况, 不应该的返回情况要用ASSERT来确认。
建议6-1:编写可重入函数时,应注意局部变量的使用(如编写C/C++语言的可重入函数时,应使用auto即缺省态局部变量或寄存器变量)。
说明:编写C/C++语言的可重入函数时,不应使用static局部变量,否则必须经过特殊处理,才能使函数具有可重入性。
建议6-2:在同一项目组应明确规定,对接口函数参数的合法性检查应由函数的调用者负责还是由接口函数本身负责,缺省是由函数调用者负责。
说明:对于模块间接口函数的参数的合法性检查这一问题,往往有两个极端现象,即:要么是调用者和被调用者对参数均不作合法性检查,结果就遗漏了合法性检查这一必要的处理过程,造成问题隐患;要么就是调用者和被调用者均对参数进行合法性检查,这种情况虽不会造成问题,但产生了冗余代码,降低了效率。
建议6-3:函数的规模尽量限制在200行以内。
说明:不包括注释和空格行。
建议6-4:一个函数仅完成一件功能。
说明:多功能集于一身的函数,很可能使函数的理解、测试、维护等变得困难。
规则6-2:尽量写类的构造、拷贝构造、析构和赋值函数 ,而不使用系统缺省的。
说明:编译器以“位拷贝”的方式自动生成缺省的拷贝构造函数和赋值函数函数 ,倘若类中含有指针变量,那么这两个缺省的函数就隐含了错误
示例:假设有以下的类定义:
class String { public: String(const char *str = NULL); // 普通构造函数 String(const String &other); // 拷贝构造函数