2-2:
避免使用不易理解的数字,用有意义的标识来替代。
涉及物理状态或者含有物理意义的常量,不应直接使用数字,必须用有意义的枚举或宏来代替。
蜡變黲癟報伥铉锚鈰赘籜葦。
示例:
如下的程序可读性差。
if(Trunk[index].trunk_state==0)
{
Trunk[index].trunk_state=1;
...//programcode
}
应改为如下形式。
#defineTRUNK_IDLE0
#defineTRUNK_BUSY1
if(Trunk[index].trunk_state==TRUNK_IDLE)
{
Trunk[index].trunk_state=TRUNK_BUSY;
...//programcode
}
2-3:
源程序中关系较为紧密的代码应尽可能相邻。
说明:
便于程序阅读和查找。
示例:
以下代码布局不太合理。
rect.length=10;
char_poi=str;
rect.width=5;
若按如下形式书写,可能更清晰一些。
rect.length=10;
rect.width=5;//矩形的长与宽关系较密切,放在一起。
char_poi=str;
2-4:
不要使用难懂的技巧性很高的语句,除非很有必要时。
说明:
高技巧语句不等于高效率的程序,实际上程序的效率关键在于算法。
示例:
如下表达式,考虑不周就可能出问题,也较难理解。
*stat_poi+++=1;
*++stat_poi+=1;
应分别改为如下。
*stat_poi+=1;
stat_poi++;//此二语句功能相当于“*stat_poi+++=1;”買鲷鴯譖昙膚遙闫撷凄届嬌。
++stat_poi;
*stat_poi+=1;//此二语句功能相当于“*++stat_poi+=1;”綾镝鯛駕櫬鹕踪韦辚糴飙钪。
3变量、结构
3-1:
去掉没必要的公共变量。
说明:
公共变量是增大模块间耦合的原因之一,故应减少没必要的公共变量以降低模块间的耦合度。
3-2:
仔细定义并明确公共变量的含义、作用、取值范围及公共变量间的关系。
说明:
在对变量声明的同时,应对其含义、作用及取值范围进行注释说明,同时若有必要还应说明与其它变量的关系。
驅踬髏彦浃绥譎饴憂锦諑琼。
3-3:
明确公共变量与操作此公共变量的函数或过程的关系,如访问、修改及创建等。
说明:
明确过程操作变量的关系后,将有利于程序的进一步优化、单元测试、系统联调以及代码维护等。
这种关系的说明可在注释或文档中描述。
猫虿驢绘燈鮒诛髅貺庑献鵬。
示例:
在源文件中,可按如下注释形式说明。
RELATIONSystem_InitInput_RecPrint_RecStat_Score锹籁饗迳琐筆襖鸥娅薔嗚訝。
StudentCreateModifyAccessAccess構氽頑黉碩饨荠龈话骛門戲。
ScoreCreateModifyAccessAccess,Modify輒峄陽檉簖疖網儂號泶蛴镧。
注:
RELATION为操作关系;System_Init、Input_Rec、Print_Rec、Stat_Score为四个不同的函数;Student、Score为两个全局变量;Create表示创建,Modify表示修改,Access表示访问。
尧侧閆繭絳闕绚勵蜆贅瀝纰。
其中,函数Input_Rec、Stat_Score都可修改变量Score,故此变量将引起函数间较大的耦合,并可能增加代码测试、维护的难度。
识饒鎂錕缢灩筧嚌俨淒侬减。
3-4:
当向公共变量传递数据时,要十分小心,防止赋与不合理的值或越界等现象发生。
说明:
对公共变量赋值时,若有必要应进行合法性检查,以提高代码的可靠性、稳定性。
3-5:
防止局部变量与公共变量同名。
说明:
若使用了较好的命名规则,那么此问题可自动消除。
3-6:
严禁使用未经初始化的变量作为右值。
说明:
特别是在C/C++中引用未经赋值的指针,经常会引起系统崩溃。
3-7:
构造仅有一个模块或函数可以修改、创建,而其余有关模块或函数只访问的公共变量,防止多个不同模块或函数都可以修改、创建同一公共变量的现象。
凍鈹鋨劳臘锴痫婦胫籴铍賄。
说明:
降低公共变量耦合度。
3-8:
使用严格形式定义的、可移植的数据类型,尽量不要使用与具体硬件或软件环境关系密切的变量。
说明:
使用标准的数据类型,有利于程序的移植。
示例:
如下例子(在DOS下BC3.1环境中),在移植时可能产生问题。
voidmain()
{
registerintindex;//寄存器变量
_AX=0x4000;//_AX是BC3.1提供的寄存器“伪变量”
...//programcode
}
3-9结构的功能要单一,是针对一种事务的抽象。
说明:
设计结构时应力争使结构代表一种现实事务的抽象,而不是同时代表多种。
结构中的各元素应代表同一事务的不同侧面,而不应把描述没有关系或关系很弱的不同事务的元素放到同一结构中。
恥諤銪灭萦欢煬鞏鹜錦聰櫻。
示例:
如下结构不太清晰、合理。
typedefstructSTUDENT_STRU
{
unsignedcharname[8];/*student'sname*/
unsignedcharage;/*student'sage*/
unsignedcharsex;/*student'ssex,asfollows*/鯊腎鑰诎褳鉀沩懼統庫摇饬。
/*0-FEMALE;1-MALE*/
unsignedchar
teacher_name[8];/*thestudentteacher'sname*/
unisgnedchar
teacher_sex;/*histeachersex*/
}STUDENT;
若改为如下,可能更合理些。
typedefstructTEACHER_STRU
{
unsignedcharname[8];/*teachername*/
unisgnedcharsex;/*teachersex,asfollows*/硕癘鄴颃诌攆檸攜驤蔹鸶胶。
/*0-FEMALE;1-MALE*/
}TEACHER;
typedefstructSTUDENT_STRU
{
unsignedcharname[8];/*student'sname*/
unsignedcharage;/*student'sage*/
unsignedcharsex;/*student'ssex,asfollows*/阌擻輳嬪諫迁择楨秘騖輛埙。
/*0-FEMALE;1-MALE*/
unsignedintteacher_ind;/*histeacherindex*/
}STUDENT;
3-10:
不要设计面面俱到、非常灵活的数据结构。
说明:
面面俱到、灵活的数据结构反而容易引起误解和操作困难。
3-11:
不同结构间的关系不要过于复杂。
说明:
若两个结构间关系较复杂、密切,那么应合为一个结构。
示例:
如下两个结构的构造不合理。
typedefstructPERSON_ONE_STRU
{
unsignedcharname[8];
unsignedcharaddr[40];
unsignedcharsex;
unsignedcharcity[15];
}PERSON_ONE;
typedefstructPERSON_TWO_STRU
{
unsignedcharname[8];
unsignedcharage;
unsignedchartel;
}PERSON_TWO;
由于两个结构都是描述同一事物的,那么不如合成一个结构。
typedefstructPERSON_STRU
{
unsignedcharname[8];
unsignedcharage;
unsignedcharsex;
unsignedcharaddr[40];
unsignedcharcity[15];
unsignedchartel;
}PERSON;
3-12:
结构中元素的个数应适中。
若结构中元素个数过多可考虑依据某种原则把元素组成不同的子结构,以减少原结构中元素的个数。
氬嚕躑竄贸恳彈瀘颔澩纷釓。
说明:
增加结构的可理解性、可操作性和可维护性。
示例:
假如认为如上的_PERSON结构元素过多,那么可如下对之划分。
typedefstructPERSON_BASE_INFO_STRU
{
unsignedcharname[8];
unsignedcharage;
unsignedcharsex;
}PERSON_BASE_INFO;
typedefstructPERSON_ADDRESS_STRU
{
unsignedcharaddr[40];
unsignedcharcity[15];
unsignedchartel;
}PERSON_ADDRESS;
typedefstructPERSON_STRU
{
PERSON_BASE_INFOperson_base;
PERSON_ADDRESSperson_addr;
}PERSON;
3-13:
仔细设计结构中元素的布局与排列顺序,使结构容易理解、节省占用空间,并减少引起误用现象。
说明:
合理排列结构中元素顺序,可节省空间并增加可理解性。
示例:
如下结构中的位域排列,将占较大空间,可读性也稍差。
typedefstructEXAMPLE_STRU
{
unsignedintvalid:
1;
PERSONperson;
unsignedintset_flg:
1;
}EXAMPLE;
若改成如下形式,不仅可节省1字节空间,可读性也变好了。
typedefstructEXAMPLE_STRU
{
unsignedintvalid:
1;
unsignedintset_flg:
1;
PERSONperson;
}EXAMPLE;
3-14:
结构的设计要尽量考虑向前兼容和以后的版本升级,并为某些未来可能的应用保留余地(如预留一些空间等)。
釷鹆資贏車贖孙滅獅赘慶獷。
说明:
软件向前兼容的特性,是软件产品是否成功的重要标志之一。
如果要想使产品具有较好的前向兼容,那么在产品设计之初就应为以后版本升级保留一定余地,并且在产品升级时必须考虑前一版本的各种特性。
怂阐譜鯪迳導嘯畫長凉馴鸨。
3-15:
留心具体语言及编译器处理不同数据类型的原则及有关细节。
说明:
如在C语言中,static局部变量将在内存“数据区”中生成,而非static局部变量将在“堆栈”中生成。
这些细节对程序质量的保证非常重要。
谚辞調担鈧谄动禪泻類谨觋。
3-16:
编程时,要注意数据类型的强制转换。
说明:
当进行数据类型强制转换时,其数据的意义、转换后的取值等都有可能发生变化,而这些细节若考虑不周,就很有可能留下隐患。
嘰觐詿缧铴嗫偽純铪锩癱恳。
3-17:
对编译系统默认的数据类型转换,也要有充分的认识。
示例:
如下赋值,多数编译器不产生告警,但值的含义还是稍有变化。
charchr;
unsignedshortintexam;
chr=-1;
exam=chr;//编译器不产生告警,此时exam为0xFFFF。
3-18:
尽量减少没有必要的数据类型默认转换与强制转换。
3-19设计数据并使用自定义数据类型,避免数据间进行不必要的类型转换。
3-20数据类型进行恰当命名,使它成为自描述性的,以提高代码可读性。
注意其命名方式在同一产品中的统一。
熒绐譏钲鏌觶鷹緇機库圆鍰。
说明:
使用自定义类型,可以弥补编程语言提供类型少、信息量不足的缺点,并能使程序清晰、简洁。
示例:
可参考如下方式声明自定义数据类型。
下面的声明可使数据类型的使用简洁、明了。
typedefunsignedcharBYTE;
typedefunsignedshortWORD;
typedefunsignedintDWORD;
下面的声明可使数据类型具有更丰富的含义。
typedeffloatDISTANCE;
typedeffloatSCORE;
3-21用于分布式环境或不同CPU间通信环境的数据结构时,必须考虑机器的字节顺序、使用的位域及字节对齐等问题。
鶼渍螻偉阅劍鲰腎邏蘞阕簣。
说明:
比如IntelCPU与68360CPU,在处理位域及整数时,其在内存存放的“顺序”正好相反。
纣忧蔣氳頑莶驅藥悯骛覲僨。
示例:
假如有如下短整数及结构。
unsignedshortintexam;
typedefstructEXAM_BIT_STRU
{/*Intel68360*/
unsignedintA1:
1;/*bit07*/
unsignedintA2:
1;/*bit16*/
unsignedintA3:
1;/*bit25*/
}EXAM_BIT;
如下是IntelCPU生成短整数及位域的方式。
内存:
012...(从低到高,以字节为单位)
examexam低字节exam高字节
内存:
0bit1bit2bit...(字节的各“位”)颖刍莖蛺饽亿顿裊赔泷涨负。
EXAM_BITA1A2A3
如下是68360CPU生成短整数及位域的方式。
内存:
012...(从低到高,以字节为单位)
examexam高字节exam低字节
内存:
7bit6bit5bit...(字节的各“位”)濫驂膽閉驟羥闈詔寢賻減栖。
EXAM_BITA1A2A3
说明:
在对齐方式下,CPU的运行效率要快得多。
示例:
如下图,当一个long型数(如图中long1)在内存中的位置正好与内存的字边界对齐时,CPU存取这个数只需访问一次内存,而当一个long型数(如图中的long2)在内存中的位置跨越了字边界时,CPU存取这个数就需要多次访问内存,如i960cx访问这样的数需读内存三次(一个BYTE、一个SHORT、一个BYTE,由CPU的微代码执行,对软件透明),所有对齐方式下CPU的运行效率明显快多了。
銚銻縵哜鳗鸿锓謎諏涼鏗穎。
18162432
-----------