c++程序设计规范_第1页
c++程序设计规范_第2页
c++程序设计规范_第3页
c++程序设计规范_第4页
c++程序设计规范_第5页
已阅读5页,还剩53页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、ANSIANSI C/C+C/C+程序设计规范程序设计规范 文件编号: SDSI-QG-28- 01-01 起草部门: 审 核 人: 批 准 人: 批准日期:2008 年 4 月 版本标识: 1.0 版 目目录录 1目的目的.3 2定义定义.3 3程序设计要求程序设计要求.3 4程序风格定义程序风格定义.4 4.1编程风格.4 4.1.1书写风格.4 4.1.2程序结构.4 4.1.3程序注释.5 4.1.4声明.6 4.1.5临时变量.6 4.2一些规则及建议:.6 5命名规范命名规范.6 5.1详细定义.7 5.1.1函数(Function).7 5.1.2变量命名规范.7 5.1.3常用

2、变量的规定:.8 5.2类定义规范.8 5.2.1类的命名.8 5.2.2类的注释.8 5.2.3类的声明.9 1 目的目的 为使整个系统保持统一和一致的编程风格及技术,提高程序代码的规范化 程度,制定该部分的规范。这些规范可以提高编码质量、增强可读性、提高排 错的容易程度、加强可维护性、以及提高代码的可重用性和可移植性。 1.1 定义定义 程序块:是整个 C/C+语言程序中完成某一细分功能的具有相对独立性的一 段程序,其主要内容包括注释、变量定义及程序正文三部分组成。 子程序块:程序块中的某一细分功能的程序块称为子程序块。 临时变量:临时变量是每次赋值的作用域较小,一般不应超过五行程序。 临

3、时变量的名字本身只是说明了该变量是一个临时的操作数,不具有任何意义, 但在某一作用域内代表不同的具体含义。 2 程序设计要求程序设计要求 一、据所确定的标准进行程序设计。 二、模块内的耦合度要高,模块间的耦合度要低。在修改一个模块时,尽量不 要对其它模块造成影响,若影响较大,有必要重新规划模块。 三、每个程序模块的行数不限,但对于程序模块中相对独立性较高的程序块最 好作成函数,每个函数的代码行数原则上不超过 200 行,经常使用的函数最好经常使用的函数最好 做成函数库,必须保证在整个系统中同名的函数有相同的定义。做成函数库,必须保证在整个系统中同名的函数有相同的定义。 四、尽量为程序块加上明确

4、的汉语注释。对于较复杂的程序或算法需要注释文 档,并在程序中注明注释文档及在文档中注明程序名。 3 开发规范开发规范 3.1 风格规范风格规范 3.1.1 缩进风格缩进风格 3.1.1.1概述概述 缩进用于提高代码的可阅读性,缩进通常采用 TAB 键来控制缩进风格,但为了不同 TAB 值的问题,缩进采用空格缩进。在 UE 中,通常将 TAB 设置成为 2 个空格。 3.1.1.2要求描述要求描述 程序采用缩进风格,在需要缩进的地方使用 2 个空格个空格进行缩进。 函数或过程的开始、结构的定义及循环、判断等语句中的代码都要采用缩进风格, case 语句下的情况处理语句也要遵从语句缩进要求。 3.

5、1.1.3示例示例 无 3.1.2 代码块分隔代码块分隔 3.1.2.1概述概述 相对独立的短代码、变量定义需要分隔开,在读代码时可以方便的区分出独立代码。 3.1.2.2要求描述要求描述 在代码之间、变量定义之后使用一行空行一行空行来分隔代码,用于区分代码。 3.1.2.3示例示例 if (!valid_ni(ni) . /* program code*/ repssn_ind = ssn_dataindex.repssn_index; repssn_ni = ssn_dataindex.ni; 3.1.3 长语句分隔长语句分隔 3.1.3.1概述概述 通常情况下屏幕长度可以容纳超过 80

6、例字符,但为适应多种屏幕(如 VI) ,且一行过 长大多数人心理无法承受,所以长语句要分隔。大多数情况下建议单行代码长度不要 超过 80 个字符,通常情况下可以使用各种方法缩减单行代码。 3.1.3.2要求描述要求描述 较长的语句(80 字符)要分成多行书写分成多行书写,长表达式要在低优先级操作符处划分新行, 操作符放在新行之首,划分出的新行要进行适当的缩进,使排版整齐,语句可读。 3.1.3.3示例示例 单条语句单条语句: perm_count_msg.head.len = NO7_TO_STAT_PERM_COUNT_LEN + STAT_SIZE_PER_FRAM * sizeof( _

7、UL ); act_task_tableframe_id * STAT_TASK_CHECK_NUMBER + index.occupied = stat_poiindex.occupied; act_task_tabletaskno.duration_true_or_false = SYS_get_sccp_statistic_state( stat_item ); report_or_not_flag = (taskno MAX_ACT_TASK_NUMBER) 循环、判断类循环、判断类: if (taskno max_act_task_number) (i BufferKeywordwo

8、rd_index.word_length) i+, j+) . /* program code*/ for (i = 0, j = 0; (i first_word_length) (2)比较操作符, 赋值操作符=、 +=,算术操作符+、%,逻辑操作符 a *= 2; a = b 2; (3)!、+、-、 /* 内容操作*与内容之间*/ flag = !isEmpty; /* 非操作!与内容之间*/ p = /* 地址操作 /* +,-与内容之间*/ (4)-、.前后不加空格。 p-id = pid; /* -指针前后不加空格*/ (5) if、for、while、switch 等与后面的括号

9、间应加空格,使 if 等关键字更为 突出、明显。 if (a = b 3.2.6 注释位置注释位置 3.2.6.1概述概述 注释要清晰的表明注释的是那块代码,而不得采用非常规的注释需要进行分析才知道 注释的那块代码。 3.2.6.2要求描述要求描述 注释应与其描述的代码相近,对代码的注释应放在其上方或右方(对单条语句的注释) 相邻位置,不可放在下面,如放于上方则需与其上面的代码用空行隔开。 除非必要,不应在代码或表达中间插入注释,否则容易使代码可理解性变差。 3.2.6.3示例示例 /*打开动态链接库*/ pLib = dlopen(LIBBILLSO, RTLD_LAZY); 3.2.7 变

10、量常量注释变量常量注释 3.2.7.1概述概述 变量常量注释用于阅读者可以清晰的知道此变量的用途。 3.2.7.2要求描述要求描述 对于所有有物理含义的变量、常量,如果其命名不是充分自注释的,在声明时都必须 加以注释,说明其物理含义。变量、常量、宏的注释应放在其上方相邻位置或右方。 数据结构声明(包括数组、结构、类、枚举等),如果其命名不是充分自注释的,必须 加以注释。对数据结构的注释应放在其上方相邻位置,不可放在下面;对结构中的每 个域的注释放在此域的右方。 全局变量要有较详细的注释,包括对其功能、取值范围、哪些函数或过程存取它以及 存取时注意事项等的说明。 3.2.7.3示例示例 #def

11、ineALLOW_UNDEAL0/ 不允许处理 /*模块调用执行存储过程结构体*/ typedef struct _Proc_Exec int64proc_id;/模块标识 har ex_sql_name20;/执行名称 T_Proc_Exec; 3.2.8 注释缩进注释缩进 3.2.8.1概述概述 注释缩进采用与注释的代码相同规则。 3.2.8.2要求描述要求描述 注释与所描述内容进行同样的缩排。 3.2.8.3示例示例 void example_fun( void ) /* 注释 1 */ CodeBlock One /* 注释 2*/ CodeBlock Two 3.2.9 注释与空行注

12、释与空行 3.2.9.1概述概述 为美观注释上要有空行。 3.2.9.2要求描述要求描述 将注释与其上面的代码用空行隔开。 3.2.9.3示例示例 /* 代码一注释 */ program code one /* 代码二注释 */ program code two 3.2.10跳转注释跳转注释 3.2.10.1 概述概述 跳转语句往往是程序实现某一特定功能的关键,对于维护人员来说,良好的注释帮助 更好的理解程序,有时甚至优于看设计文档。 。 3.2.10.2 要求描述要求描述 对变量的定义和分支语句(条件分支、循环语句等)必须编写注释。 对于 switch 语句下的 case 语句,如果因为特殊

13、情况需要处理完一个 case 后进入下一个 case 处理,必须在该 case 语句处理完、下一个 case 语句前加上明确的注释。 3.2.10.3 示例示例 case CMD_UP: /* 注释内容 */ ProcessUp(); break; 3.2.11注释语言注释语言 3.2.11.1 概述概述 注释语言不统一,影响程序易读性和外观排版,出于对维护人员的考虑,建议使用中 文,除非标准英语注释 3.2.11.2 要求描述要求描述 标准英语或中文,尽量用中文。 3.2.11.3 示例示例 无 3.3 标识符规范标识符规范 3.3.1 清晰明了清晰明了 3.3.1.1概述概述 标识符的命名

14、要清晰、明了,有明确含义,同时使用完整的单词或大家基本可以理解 的缩写,避免使人产生误解。 3.3.1.2要求描述要求描述 较短的单词可通过去掉“元音”形成缩写;较长的单词可取单词的头几个字母形成缩 写;一些单词有大家公认的缩写。 对于变量命名,禁止取单个字符(如 i、j、k.) ,建议除了要有具体含义外,还能表明 其变量类型、数据类型等,但 i、j、k 作局部循环变量是允许的。 3.3.1.3示例示例 temp 可缩写为 tmp ; flag 可缩写为 flg ; statistic 可缩写为 stat ; increment 可缩写为 inc ; message 可缩写为 msg ; 3.

15、3.2 风格风格 3.3.2.1概述概述 命名规范必须与所使用的系统风格保持一致,并在同一项目中统一。 3.3.2.2要求描述要求描述 采用 UNIX 的全小写加下划线的风格或大小写混排的方式,不要使用大小写与下划线 混排的方式,用作特殊标识如标识成员变量或全局变量的 m_和 g_,其后加上大小写 混排的方式是允许的。 除非必要,不要用数字或较奇怪的字符来定义标识符。 3.3.2.3示例示例 错误风格:错误风格: #define _EXAMPLE_0_TEST_ #define _EXAMPLE_1_TEST_ void set_sls00( BYTE sls ); 正确风格:正确风格: #d

16、efine _EXAMPLE_UNIT_TEST_ #define _EXAMPLE_ASSERT_TEST_ void set_udt_msg_sls( BYTE sls ); 3.4 过程规范过程规范 3.4.1 返回值返回值 3.4.1.1概述概述 对于函数的返回值要进行全面的判断,由于返回值判断不周可能会导致程序出错但没 有正确的报告。 3.4.1.2要求描述要求描述 对所调用函数的错误返回码要仔细、全面地处理。 3.4.1.3示例示例 无 3.4.2 过程长度过程长度 3.4.2.1概述概述 一个函数的代码行是没有限制的,但为了容易阅读代码长度应限制在两屏可观的程度, 通常情况下代码

17、行不应超过行。 3.4.2.2要求描述要求描述 代码长度不超过行。 3.4.2.3示例示例 无 3.4.3 一个功能一个函数一个功能一个函数 3.4.3.1概述概述 一个函数可以完成很多功能,但大多数情况下,一个函数只完成一个功能。一般通过 它做什么的句式来验证函数是否是有效的。如果需要它做什么和什么,通常不是个好 函数。 在比如 MAX 算法,通常情况下一个?:语句就可以实现,但用函数来实现在后续的维 护中可以更好的进行升级。 还有一种比较极端的情况是,一个函数实现了过多的功能,此函数通常不易理解。 3.4.3.2要求描述要求描述 一个函数仅完成一件功能。 3.4.3.3示例示例 错误例子:

18、错误例子: value = ( a b ) ? a : b ; 正确例子:正确例子: int max (int a, int b) return (a b) ? a : b); value = max (a, b); 或改为如下。 #define MAX (a, b) (a) (b) ? (a) : (b) value = MAX (a, b); 3.5 可读性规范可读性规范 3.5.1 运算符优先级运算符优先级 3.5.1.1概述概述 注意运算符的优先级,并用括号明确表达式的操作顺序,避免使用默认优先级。 3.5.1.2要求描述要求描述 防止阅读程序时产生误解,防止因默认的优先级与设计思想不

19、符而导致程序出错。 3.5.1.3示例示例 word = (high 8) | low (1) if (a | b) . / program code 优秀的例子:优秀的例子: #define TRUNK_IDLE 0 #define TRUNK_BUSY 1 if (Trunkindex.trunk_state = TRUNK_IDLE) Trunkindex.trunk_state = TRUNK_BUSY; . / program code 3.5.3 关系紧密紧凑关系紧密紧凑 3.5.3.1概述概述 在代码中关系联系比较紧凑的代码尽量写在一起方便阅读者阅读程序。 3.5.3.2要求描述

20、要求描述 源程序中关系较为紧密的代码应尽可能相邻。 3.5.3.3示例示例 错误的例子:错误的例子: rect.length = 10; char_poi = str; rect.width = 5; 优秀的例子:优秀的例子: rect.length = 10; rect.width = 5; / 矩形的长与宽关系较密切,放在一起。 char_poi = str; 3.5.4 高技巧高技巧!=高可读高可读 3.5.4.1概述概述 程序可以写的非常复杂,但技巧性高的代码并不一定是高效率的,效率一般从代码的 算法来考虑,不要考虑从汇编角度考虑问题。 3.5.4.2要求描述要求描述 高技巧语句不等于

21、高效率的程序,实际上程序的效率关键在于算法。 3.5.4.3示例示例 错误的例子:错误的例子: * stat_poi + += 1; * + stat_poi += 1; 优秀的例子:优秀的例子: *stat_poi += 1; stat_poi+; / 此二语句功能相当于“ * stat_poi + += 1; ” + stat_poi; *stat_poi += 1; / 此二语句功能相当于“ * + stat_poi += 1; ” 3.6 变量规范变量规范 3.6.1 慎用全局变量慎用全局变量 3.6.1.1概述概述 全局变量通常是万恶之源,如非确实必要禁止使用全局变量。 3.6.1.

22、2要求描述要求描述 如需使用全局变量须向项目负责人书面申请,且在全局变量做详细注释,表明此全局 变量的用途,使用的函数,函数间的交互。 3.6.1.3示例示例 无。 3.6.2 变量初始化变量初始化 3.6.2.1概述概述 变量不初始化就使用通常会产生不可预料的后果。 3.6.2.2要求描述要求描述 每个变量都需要进行初始化特别是指针变量。 3.6.2.3示例示例 无。 3.6.3 变量定义变量定义 3.6.3.1概述概述 变量的定义和主机、编译器有比较大的关系,部分变量类型在部分系统上是不支持的, 尤其要考虑位主机和位主机的关系。 3.6.3.2要求描述要求描述 变量只使用三种 INT32_

23、T,INT64_T,CHAR_T,且不要使用特别奇怪的变量前缀,比如 register 等,慎用 static 类型。 INT32_T,INT64_T,CHAR_T 的定义在系统的头文件中定义,根据不同的主机不同的编 译器使用不同的实际定义。 3.6.3.3示例示例 #define INT32 int #define INT64 long/*位主机*/ #define INT64 long long/*32 位主机*/ 3.6.4 结构定义结构定义 3.6.4.1概述概述 设计结构时应力争使结构代表一种现实事务的抽象,而不是同时代表多种。结构中的 各元素应代表同一事务的不同侧面,而不应把描述没

24、有关系或关系很弱的不同事务的 元素放到同一结构中。 3.6.4.2要求描述要求描述 结构的功能要单一,是针对一种事务的抽象,而不是一个大杂烩。 面面俱到、灵活的数据结构反而容易引起误解和操作困难。 3.6.4.3示例示例 错误例子:错误例子: typedef struct STUDENT_STRU unsigned char name8; /* students name */ unsigned char age; /* students age */ unsigned char sex; /* students sex, as follows */ /* 0 - FEMALE; 1 - MA

25、LE */ unsigned char teacher_name8; /* the student teachers name */ unisgned char teacher_sex; /* his teacher sex */ STUDENT; 正确例子:正确例子: typedef struct TEACHER_STRU unsigned char name8; /* teacher name */ unisgned char sex; /* teacher sex, as follows */ /* 0 - FEMALE; 1 - MALE */ TEACHER; typedef str

26、uct STUDENT_STRU unsigned char name8; /* students name */ unsigned char age; /* students age */ unsigned char sex; /* students sex, as follows */ /* 0 - FEMALE; 1 - MALE */ unsigned int teacher_ind; /* his teacher index */ STUDENT; 错误例子:错误例子: typedef struct PERSON_ONE_STRU unsigned char name8; unsig

27、ned char addr40; unsigned char sex; unsigned char city15; PERSON_ONE; typedef struct PERSON_TWO_STRU unsigned char name8; unsigned char age; unsigned char tel; PERSON_TWO; 正确例子:正确例子: typedef struct PERSON_STRU unsigned char name8; unsigned char age; unsigned char sex; unsigned char addr40; unsigned

28、char city15; unsigned char tel; PERSON; 3.6.5 结构成员个数结构成员个数 3.6.5.1概述概述 一个结构体通常不要使用太多的成员,除非必要。 3.6.5.2要求描述要求描述 结构中元素的个数应适中。若结构中元素个数过多可考虑依据某种原则把元素组成不 同的子结构,以减少原结构中元素的个数 3.6.5.3示例示例 3.6.6 字节顺序字节顺序 3.6.6.1概述概述 3.6.6.2要求描述要求描述 当声明用于分布式环境或不同 CPU 间通信环境的数据结构时,必须考虑机器的字节顺 序、使用的位域及字节对齐等问题 。 3.6.6.3示例示例 比如 Inte

29、l CPU 与 68360 CPU,在处理位域及整数时,其在内存存放的“顺序” 正好相反。 示例:假如有如下短整数及结构。 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 . (从低到高,以字节为单位) e

30、xam exam 低字节 exam 高字节 内存: 0 bit 1 bit 2 bit . (字节的各“位” ) EXAM_BIT A1 A2 A3 如下是 68360 CPU 生成短整数及位域的方式。 内存: 0 1 2 . (从低到高,以字节为单位) exam exam 高字节 exam 低字节 内存: 7 bit 6 bit 5 bit . (字节的各“位” ) EXAM_BIT A1 A2 A3 说明:在对齐方式下,CPU 的运行效率要快得多。 示例:如下图,当一个 long 型数(如图中 long1)在内存中的位置正好与内存的字 边界对齐时,CPU 存取这个数只需访问一次内存,而当一

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

32、1.1概述概述 3.7.1.2要求描述要求描述 在同一项目组或产品组内,要有一套统一的为集成测试与系统联调准备的调测开关及 相应打印函数,并且要有详细的说明。调测打印出的信息串的格式要有统一的形式。 信息串中至少要有所在模块名(或源文件名)及行号。 编程的同时要为单元测试选择恰当的测试点,并仔细构造测试代码、测试用例,同时 给出明确的注释说明。测试代码部分应作为(模块中的)一个子模块,以方便测试代 码在模块中的安装与拆卸(通过调测开关) 。 在软件系统中设置与取消有关测试手段,不能对软件实现的功能等产生影响。 用调测开关来切换软件的 DEBUG 版和正式版,而不要同时存在正式版本和 DEBUG

33、 版本的不同源文件,以减少维护的难度。 软件的 DEBUG 版本和发行版本应该统一维护,不允许分家,并且要时刻注意保证两 个版本在实现功能上的一致性。 在编写代码之前,应预先设计好程序调试与测试的方法和手段,并设计好各种调测开 关及相应测试代码如打印函数等。 编写防错程序,然后在处理错误之后可用断言宣布发生错误。 3.7.1.3示例示例 示例:假如某模块收到通信链路上的消息,则应对消息的合法性进行检查,若消息类 别不是通信协议中规定的,则应进行出错处理,之后可用断言报告,如下例。 #ifdef _EXAM_ASSERT_TEST_ / 若使用断言测试 /* Notice: this funct

34、ion does not call abort to exit program */ void assert_report( char * file_name, unsigned int line_no ) printf( nEXAMError Report: %s, line %un, file_name, line_no ); #define ASSERT_REPORT( condition ) if ( condition ) / 若条件成立,则无动作 NULL; else / 否则报告 assert_report ( _FILE_, _LINE_ ) #else / 若不使用断言测试

35、#define ASSERT_REPORT( condition ) NULL #endif /* end of ASSERT */ int msg_handle( unsigned char msg_name, unsigned char * msg ) switch( msg_name ) case MSG_ONE: . / 消息 MSG_ONE 处理 return MSG_HANDLE_SUCCESS; . / 其它合法消息处理 default: . / 消息出错处理 ASSERT_REPORT( FALSE ); / “合法”消息不成立,报告 return MSG_HANDLE_ERR

36、OR; 3.7.2 断言断言 3.7.2.1概述概述 断言是对某种假设条件进行检查(可理解为若条件成立则无动作,否则应报告) ,它可 以快速发现并定位软件问题,同时对系统错误进行自动报警。断言可以对在系统中隐藏很 深,用其它手段极难发现的问题进行定位,从而缩短软件问题定位时间,提高系统的可测 性。实际应用时,可根据具体情况灵活地设计断言。 断言是用来处理不应该发生的错误情况的,对于可能会发生的且必须处理的情况要写 防错程序,而不是断言。如某模块收到其它模块或链路上的消息后,要对消息的合理性进 行检查,此过程为正常的错误检查,不能用断言来实现。 程序运行时所需的软硬件环境及配置要求,不能用断言来

37、检查,而必须由一段专门代 码处理。用断言仅可对程序开发环境中的假设及所配置的某版本软硬件是否具有某种功能 的假设进行检查。如某网卡是否在系统运行环境中配置了,应由程序中正式代码来检查; 而此网卡是否具有某设想的功能,则可由断言来检查。 对编译器提供的功能及特性假设可用断言检查,原因是软件最终产品(即运行代码或 机器码)与编译器已没有任何直接关系,即软件运行过程中(注意不是编译过程中)不会 也不应该对编译器的功能提出任何需求。 3.7.2.2要求描述要求描述 使用断言来发现软件问题,提高代码可测性。 用断言来检查程序正常运行时不应发生但在调测时有可能发生的非法情况。 不能用断言来检查最终产品肯定

38、会出现且必须处理的错误情况。 用断言确认函数的参数。 对较复杂的断言加上明确的注释。 用断言保证没有定义的特性或功能不被使用。 用断言对程序开发环境(OS/Compiler/Hardware)的假设进行检查。 正式软件产品中应把断言及其它调测代码去掉(即把有关的调测开关关掉) 。 3.7.2.3示例示例 #ifdef _EXAM_ASSERT_TEST_ / 若使用断言测试 void exam_assert( char * file_name, unsigned int line_no ) printf( nEXAMAssert failed: %s, line %un, file_name,

39、 line_no ); abort( ); #define EXAM_ASSERT( condition ) if (condition) / 若条件成立,则无动作 NULL; else / 否则报告 exam_assert( _FILE_, _LINE_ ) #else / 若不使用断言测试 #define EXAM_ASSERT(condition) NULL #endif /* end of ASSERT */ 3.8 效率规范效率规范 3.8.1 写代码时即注意效率写代码时即注意效率 3.8.1.1概述概述 代码效率分为全局效率、局部效率、时间效率及空间效率。全局效率是站在整个系统 的

40、角度上的系统效率;局部效率是站在模块或函数角度上的效率;时间效率是程序处 理输入任务所需的时间长短;空间效率是程序所需内存空间,如机器代码空间大小、 数据空间大小、栈空间大小等。 3.8.1.2要求描述要求描述 编程时要经常注意代码的效率,但要在保证软件系统的正确性、稳定性、可读性及可 测性的前提下,提高代码效率。局部效率应为全局效率服务,不能因为提高局部效率 而对全局效率造成影响。 3.8.1.3示例示例 无 3.8.2 空间效率空间效率 3.8.2.1概述概述 大部分情况下空间占用都是个主要的问题,在系统内存有限的情况下,如何缩减内存 占用都是问题,比如内存是 10G,但每个进程的空间占用

41、 1G,则表明并发处理只能启 动 10 个进程。 3.8.2.2要求描述要求描述 通过对系统数据结构的划分与组织的改进,以及对程序算法的优化来提高空间效率。 人为的缩减变量可用值是不可取的,比如电话号码最长可以是位,但通常情况下 是位或者位,为了缩减这部分空间把电话号码的长度改为位,是不可取的, 而是通过结构的调整来缩减空间占用,当然动态的内存占用分配会减少空间占用,但 存在的问题是效率会降低,且后期维护代码复杂。 3.8.2.3示例示例 如下记录学生学习成绩的结构不合理。 typedef unsigned char BYTE; typedef unsigned short WORD; typ

42、edef struct STUDENT_SCORE_STRU BYTE name8; BYTE age; BYTE sex; BYTE class; BYTE subject; float score; STUDENT_SCORE; 因为每位学生都有多科学习成绩,故如上结构将占用较大空间。应如下改进(分为两 个结构) ,总的存贮空间将变小,操作也变得更方便。 typedef struct STUDENT_STRU BYTE name8; BYTE age; BYTE sex; BYTE class; STUDENT; typedef struct STUDENT_SCORE_STRU WORD

43、 student_index; BYTE subject; float score; STUDENT_SCORE; 3.8.3 时间效率时间效率 3.8.3.1概述概述 时间效率的关键之处在于减少计算量,减少计算量大体有两个思路,:通过调整代 码结构缩减计算量,这种方法在大多数情况是有效的,但提高性能比率可能不会很高。 :通过调整算法缩减计算量。 3.8.3.2要求描述要求描述 通过改进算法提高效率。 优化最关键的的应用代码。 优化最占时间的关键代码。 谨慎使用汇编代码,大多数情况下是没有必要使用汇编代码,如需使用需与项目负责 人申请。 对输入输出部分要仔细考虑,通常在此会有效率的瓶颈。 3.

44、8.3.3示例示例 无。 3.8.4 多重循环多重循环 3.8.4.1概述概述 时间效率的关键之处在于减少计算量,减少计算量大体有两个思路,:通过调整代 码结构缩减计算量,这种方法在大多数情况是有效的,但提高性能比率可能不会很高。 :通过调整算法缩减计算量。 3.8.4.2要求描述要求描述 在多重循环中,应将最忙的循环放在最内层。且尽量减少循环嵌套层次。最忙的循环放在最内层。且尽量减少循环嵌套层次。 3.8.4.3示例示例 下面示例并不合理,但确是优化的一个思路。 如下代码效率不高。 for (row = 0; row 100; row+) If(arowcol)continue; for (

45、col = 0; col 5; col+) sum += arowcol; 可以改为如下方式,以提高效率。 for (col = 0; col 5; col+) If(arowcol)continue; for (row = 0; row 100; row+) sum += arowcol; 3.8.5 结构调整结构调整 3.8.5.1概述概述 3.8.5.2要求描述要求描述 避免循环体内含判断语句,应将循环语句置于判断语句的代码块之中。 3.8.5.3示例示例 如下代码效率稍低。 for (ind = 0; ind MAX_RECT_NUMBER; ind+) if (data_type =

46、 RECT_AREA) area_sum += rect_areaind; else rect_length_sum += rectind.length; rect_width_sum += rectind.width; 因为判断语句与循环变量无关,故可如下改进,以减少判断次数。 if (data_type = RECT_AREA) for (ind = 0; ind MAX_RECT_NUMBER; ind+) area_sum += rect_areaind; else for (ind = 0; ind MAX_RECT_NUMBER; ind+) rect_length_sum +=

47、rectind.length; rect_width_sum += rectind.width; 3.8.6 常量预先计算常量预先计算 3.8.6.1概述概述 3.8.6.2要求描述要求描述 对于长使用的计算常量可以预先定义常量计算出来。 3.8.6.3示例示例 #define PAI 3.1416 radius = circle_length / (2 * PAI); 应如下把浮点除法改为浮点乘法。 #define PAI_RECIPROCAL (1 / 3.1416 ) / 编译器编译时,将生成具体浮 点数 radius = circle_length * PAI_RECIPROCAL /

48、 2; 3.8.7 避免数据库交互避免数据库交互 3.8.7.1概述概述 3.8.7.2要求描述要求描述 尽量避免频繁的与数据库交互,通常数据库交互每秒不会超过 10000 次,每次计算都 与数据库交互则会使计算效率低于 10000 次/秒。 通常的解决办法是使用缓存或者使用共享内存的方式降低数据库交互。比如序列号的 获取采用每 100000 次获取一次。批价资料存放到共享内存中,资料更新采用单独更新 进程。 另一种办法是把数据库交互部分做成一个单独的进程,主进程不直接与数据库交互, 此方法通常用于非关键是计算,比如日志输出到数据库,其它需要输入到数据库的内 容。 3.8.7.3示例示例 无

49、3.9 质量规范质量规范 3.9.1 质量优先质量优先 3.9.1.1概述概述 3.9.1.2要求描述要求描述 代码质量保证优先原则代码质量保证优先原则 (1)正确性,指程序要实现设计要求的功能。 (2)稳定性、安全性,指程序稳定、可靠、安全。 (3)可测试性,指程序要具有良好的可测试性。 (4)规范/可读性,指程序书写风格、命名规则等要符合规范。 (5)全局效率,指软件系统的整体效率。 (6)局部效率,指某个模块/子模块/函数的本身效率。 (7)个人表达方式/个人方便性,指个人编程习惯。 3.9.1.3示例示例 无 3.9.2 资源使用资源使用 3.9.2.1概述概述 3.9.2.2要求描述

50、要求描述 只引用属于自己的存贮空间。 防止引用已经释放的内存空间。 过程/函数中分配的内存,在过程/函数退出之前要释放。 过程/函数中申请的(为打开文件而使用的)文件句柄,在过程/函数退出之前要关闭。 防止内存操作越界。 3.9.2.3示例示例 无 3.9.3 边界问题边界问题 3.9.3.1概述概述 3.9.3.2要求描述要求描述 编程时,要防止差 1 错误。此类错误一般是由于把“=”误写成“=”误写 成“”等造成的,由此引起的后果,很多情况下是很严重的,所以编程时,一定要 在这些地方小心。当编完程序后,应对这些操作符进行彻底检查。 使用变量时要注意其边界值的情况。 时刻注意表达式是否会上溢、下溢。 3.9.3.3示例示例 如下程序将造成变量下溢。 unsigned

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论