C++代码规范

C++代码规范
C++代码规范

C/C++编码规范:

今天人们越来越明白软件设计更多地是一种工程,而不是一种个人艺术。由于大型产品的开发通常由很多的人协同作战,如果不统一编程规范,最终合到一起的程序,其可读性将较差,这不仅给代码的理解带来障碍,增加维护阶段的工作量,同时不规范的代码隐含错误的可能性也比较大。

BELL实验室的研究资料表明,软件错误中18%左右产生于概要设计阶段,15%左右产生于详细设计阶段,而编码阶段产生的错误占的比例则接近50%;分析表明,编码阶段产生的错误当中,语法错误大概占20%左右,而由于未严格检查软件逻辑导致的错误、函数(模块)之间接口错误及由于代码可理解度低导致优化维护阶段对代码的错误修改引起的错误则占了一半以上。可见,提高软件质量必须降低编码阶段的错误率。如何有效降低编码阶段的错误呢?BELL 实验室的研究人员制定了详细的软件编程规范,并培训每一位程序员,最终的结果把编码阶段的错误降至10%左右,同时也降低了程序的测试费用,效果相当显著。

本文从代码的可维护性(可读、可理解性、可修改性)、代码逻辑与效率、函数(模块)接口、可测试性四个方面阐述了软件编程规范,规范分成规则和建议两种,其中规则部分为强制执行项目,而建议部分则不作强制,可根据习惯取舍。

编码规范

1.排版风格

<规则1> 程序块采用缩进风格编写,缩进为4个空格位。排版不混合使用空格和TAB键。

<规则2> 在两个以上的关键字、变量、常量进行对等操作时,它们之间的操作符之前、之后或者前后要加空格;进行非对等操作时,如果是关系密切的立即操作符(如->),后不应加空格。

采用这种松散方式编写代码的目的是使代码更加清晰。例如:

(1) 逗号、分号只在后面加空格

printf("%d %d %d" , a, b, c);

(2)比较操作符, 赋值操作符"="、"+=",算术操作符"+"、"%",逻辑操作符"&&"、"&",位域操作符"<<"、"^"等双目操作符的前后加空格

if(lCurrentTime >= MAX_TIME_VALUE)

a =

b + c;

a *= 2;

a =

b ^ 2;

(3)"!"、"~"、"++"、"--"、"&"(地址运算符)等单目操作符前后不加空格

*pApple = 'a'; // 内容操作"*"与内容之间

flag = !bIsEmpty; // 非操作"!"与内容之间

p = &cMem; // 地址操作"&" 与内容之间

i++; // "++","--"与内容之间

(4)"->"、"."前后不加空格

p->id = pId; // "->"指针前后不加空格

由于留空格所产生的清晰性是相对的,所以,在已经非常清晰的语句中没有必要再留空格,如最内层的括号内侧(即左括号后面和右括号前面)不要加空格,因为在C/C++语言中括号已经是最清晰的标志了。

另外,在长语句中,如果需要加的空格非常多,那么应该保持整体清晰,而在局部不加空格。

最后,即使留空格,也不要连续留两个以上空格(为了保证缩进和排比留空除外)。

<规则3> 函数体的开始,类的定义,结构的定义,if、for、do、while、switch及case语句中的程序都应采用缩进方式,憑捄蛻}捰禀独占一行并且位于同一列,同时与引用它们的语句左对齐

例如下例不符合规范。

for ( ... ) {

... // 程序代码

}

if ( ... )

{

... // 程序代码

}

void DoExam( void )

{

... // 程序代码

}

应如下书写。

for ( ... )

{

... // 程序代码

}

if ( ... )

{

... // 程序代码

}

void DoExam( void )

{

... // 程序代码

}

<规则4> 功能相对独立的程序块之间或for、if、do、while、switch等语句前后应加一空行。

例如以下例子不符合规范。

例一:

if ( ! ValidNi( ni ) )

{

... // 程序代码

}

nRepssnInd = SsnData[ index ].nRepssnIndex ;

nRepssnNi = SsnData[ index ].ni ;

例二:

char *pContext;

int nIndex;

long lCounter;

pContext = new (CString);

if(pContext == NULL)

{

return FALSE;

}

应如下书写

例一:

if ( ! ValidNi( ni ) )

{

... // 程序代码

}

nRepssnInd = SsnData[ index ].nRepssnIndex ;

nRepssnNi = SsnData[ index ].ni ;

例二:

char *pContext;

int nIndex;

long lCounter;

pContext = new (CString);

if(pContext == NULL)

{

return FALSE;

}

<规则5> if、while、for、case、default、do等语句自占一行。

示例:如下例子不符合规范。

if(pUserCR == NULL) return;

应如下书写:

if( pUserCR == NULL )

{

return;

}

<规则6> 若语句较长(多于80字符),可分成多行写,划分出的新行要进行适应的缩进,使排版整齐,语句可读。

memset(pData->pData + pData->nCount, 0,

(m_nMax - pData->nCount) * sizeof(LPVOID));

CNoTrackObject* pValue =

(CNoTrackObject*)_afxThreadData->GetThreadValue(m_nSlot); for ( i = 0, j = 0 ; ( i < BufferKeyword[ WordIndex ].nWordLength ) && ( j < NewKeyword.nWordLength ) ; i ++ , j ++ )

{

... // 程序代码

}

<规则7> 一行最多写一条语句。

示例:如下例子不符合规范。

rect.length = 0 ; rect.width = 0 ;

rect.length = width = 0;

都应书写成:

rect.length = 0 ;

rect.width = 0 ;

<规则8> 对结构成员赋值,等号对齐。

示例:

rect.top = 0;

rect.left = 0;

rect.right = 300;

rect.bottom = 200;

<规则9> #define的各个字段对齐

以下示例不符合规范

#define MAX_TASK_NUMBER 100

#define LEFT_X 10

#define BOTTOM_Y 400

应书写成:

#define MAX_TASK_NUMBER 100

#define LEFT_X 10

#define BOTTOM_Y 400

<规则10> 不同类型的操作符混合使用时,使用括号给出优先级。

如本来是正确的代码:

if( year % 4 == 0 || year % 100 != 0 && year % 400 == 0 )

如果加上括号,则更清晰。

if((year % 4) == 0 || ((year % 100) != 0 && (year % 400) == 0)) 2. 可理解性

1.1 注释

注释的原则是有助于对程序的阅读理解,注释不宜太多也不能太少,太少不利于代码理解,太多则会对阅读产生干扰,因此只在必要的地方才加注释,而且注释要准确、易懂、尽可能简洁。注释量一般控制在30%到50%之间。

<规则1> 程序在必要的地方必须有注释,注释要准确、易懂、简洁。

例如如下注释意义不大。

/* 如果bReceiveFlag 为TRUE */

if ( bReceiveFlag == TRUE)

而如下的注释则给出了额外有用的信息。

/* 如果mtp 从连接处获得一个消息*/

if ( bReceiveFlag == TURE)

<规则2> 注释应与其描述的代码相近,对代码的注释应放在其上方或右方(对单条语句的注释)相邻位置,不可放在下面,如放于上方则需与其上面的代码用空行隔开。

示例:如下例子不符合规范。

例子1

/* 获得系统指针和网络指针的副本*/

nRepssnInd = SsnData[ index ].nRepssnIndex ;

nRepssnNi = SsnData[ index ].ni ;

例子2

nRepssnInd = SsnData[ index ].nRepssnIndex ;

nRepssnNi = SsnData[ index ].ni ;

/*获得系统指针和网络指针的副本*/

应如下书写

/*获得系统指针和网络指针的副本*/

nRepssnInd = SsnData[ index ].nRepssnIndex ;

nRepssnNi = SsnData[ index ].ni ;

<规则3> 对于所有的常量,变量,数据结构声明(包括数组、结构、类、枚举等),如果其命名不是充分自注释的,在声明时都必须加以注释,说明其含义。

示例:

/* 活动任务的数量*/

#define MAX_ACT_TASK_NUMBER 1000

#define MAX_ACT_TASK_NUMBER 1000 /*活动任务的数量*/

/* 带原始用户信息的SCCP接口*/

enum SCCP_USER_PRIMITIVE

{

N_UNITDATA_IND , /* 向SCCP用户报告单元数据已经到达*/

N_UNITDATA_REQ , /* SCCP用户的单元数据发送请求*/

} ;

<规则4> 头文件、源文件的头部,应进行注释。注释必须列出:文件名、作者、目的、功能、修改日志等。

例如:

/*********************************************

文件名:

编写者:

编写日期:

简要描述:

修改记录:

********************************************/

说明:摷蛞

修改日期、修改者及修改内容简述。

<规则5> 函数头部应进行注释,列出:函数的目的、功能、输入参数、输出参数、修改日志等。

形式如下:

/*************************************************

函数名称:

简要描述: // 函数目的、功能等的描述

输入: // 输入参数说明,包括每个参数的作用、取值说明及参数间关系,

输出: // 输出参数的说明,返回值的说明

修改日志:

*************************************************/

对一些复杂的函数,在注释中最好提供典型用法。

<规则6> 仔细定义并明确公共变量的含义、作用、取值范围及使用方法。

在对变量声明的同时,应对其含义、作用、取值范围及使用方法进行注释说明,同时若有必要还应说明与其它变量的关系。明确公共变量与操作此公共变量的函数或过程的关系,如访问、修改及创建等。

示例:

/* SCCP转换时错误代码*/

/* 全局错误代码,含义如下*/ // 变量作用、含义

/* 0 - 成功1 - GT 表错误2 -GT 错误其它值- 未使用*/ // 变量取值范围

<规则7> 对指针进行充分的注释说明,对其作用、含义、使用范围、注意事项等说明清楚。

在对指针变量、特别是比较复杂的指针变量声明时,应对其含义、作用及使用范围进行注释说明,如有必要,还应说明其使用方法、注意事项等。

示例:

/* 学生记录列表的头指针*/

/* 当在此模块中创建该列表时,该头指针必须初始化,*/

/* 这样可以利用GetListHead()获得这一列表。*/ //指针作用、含义

/* 该指针只在本模块使用,其它模块通过调用GetListHead()获取*/

/* 当使用时必须保证它非空*/ //使用范围、方法

STUDENT_RECORD *pStudentRecHead;

<规则8> 对重要代码段的功能、意图进行注释,提供有用的、额外的信息。并在该代码段的结束处加一行注释表示该段代码结束。

示例:

/* 可选通道的组合*/

if ((gsmBCIe31->radioChReq >= DUAL_HR_RCR)

&& (gsmBCIe32->radioChReq >= DUAL_HR_RCR))

{

gsmBCIe31->radioChReq = FR_RCR;

gsmBCIe32->radioChReq = FR_RCR;

}

else if ((gsmBCIe31->radioChReq >= DUAL_HR_RCR)

&& (gsmBCIe32->radioChReq == FR_RCR) )

{

gsmBCIe31->radioChReq = FR_RCR;

}

else if ((gsmBCIe31->radioChReq == FR_RCR)

&& (gsmBCIe32->radioChReq >= DUAL_HR_RCR))

{

gsmBCIe32->radioChReq = FR_RCR;

}

/* 本块结束( 可选通道组合) */

<规则9> 在switch语句中,对没有break语句的case分支加上注释说明。

示例:

switch(SubT30State)

{

case TA0:

AT(CHANNEL, "AT+FCLASS=1\r", 0);

if(T30Status != 0)

{

return(1);

}

InitFax(); /* 准备发送传真*/

AT(CHANNEL, "ATD\r",-1); /*发送CNG ,接收CED 和HDLC 标志*/

T1_Flg = 1;

iResCode = 0;

/* 没有break; */

case TA1:

iResCode = GetModemMsg(CHANNEL);

break;

default:

break;

}

<规则10> 维护代码时,要更新相应的注释,删除不再有用的注释。

保持代码、注释的一致性,避免产生误解。

1.2 命名

本文列出Visual C++的标识符命名规范。

<规则1> 标识符缩写

形成缩写的几种技术:

1) 去掉所有的不在词头的元音字母。如screen写成scrn, primtive写成prmv。

2) 使用每个单词的头一个或几个字母。如Channel Activation写成ChanActiv,Release Indication 写成RelInd。

3) 使用变量名中每个有典型意义的单词。如Count of Failure写成FailCnt。

4) 去掉无用的单词后缀ing, ed等。如Paging Request写成PagReq。

5) 使用标准的或惯用的缩写形式(包括协议文件中出现的缩写形式)。如BSIC(Base Station Identification Code)、MAP(Mobile Application Part)。

关于缩写的准则:

1) 缩写应该保持一致性。如Channel不要有时缩写成Chan,有时缩写成Ch。Length有时缩写成Len,有时缩写成len。

2) 在源代码头部加入注解来说明协议相关的、非通用缩写。

3) 标识符的长度不超过32个字符。

<规则2> 变量命名约定

参照匈牙利记法,即

[作用范围域前缀] + [前缀] + 基本类型+ 变量名

其中:

前缀是可选项,以小写字母表示;

基本类型是必选项,以小写字母表示;

变量名是必选项,可多个单词(或缩写)合在一起,每个单词首字母大写。

前缀列表如下:

前缀意义举例

g_ Global 全局变量g_MyVar

m_ 类成员变量或模块级变量m_ListBox, m_Size

s_ static 静态变量s_Count

h Handle 句柄hWnd

p Pointer 指针pTheWord

lp Long Point 长指针lpCmd

a Array 数组aErr

基本类型列表如下:

基本类型意义举例

b Boolean 布尔bIsOK

by Byte 字节byNum

c Char 字符cMyChar

i或n Intger 整数nTestNumber

u Unsigned integer 无符号整数uCount

ul Unsigned Long 无符号长整数ulTime

w Word 字wPara

dw Double Word 双字dwPara

l Long 长型lPara

f Float 浮点数fTotal

s String 字符串sTemp

sz NULL结束的字符串szTrees

fn Funtion 函数fnAdd

enm 枚举型enmDays

x,y x,y坐标

<规则3> 宏和常量的命名

宏和常量的命名规则:单词的字母全部大写,各单词之间用下划线隔开。命名举例:

#define MAX_SLOT_NUM 8

#define EI_ENCR_INFO 0x07

const int MAX_ARRAY

<规则4> 结构和结构成员的命名

结构名各单词的字母均为大写,单词间用下划线连接。可用或不用typedef,但是要保持一致,不能有的结构用typedef,有的又不用。如:

typedef struct LOCAL_SPC_TABLE_STRU

{

char cValid;

int nSpcCode[MAX_NET_NUM];

} LOCAL_SPC_TABLE ;

结构成员的命名同变量的命名规则。

<规则5> 枚举和枚举成员的命名

枚举名各单词的字母均为大写,单词间用下划线隔开。

枚举成员的命名规则:单词的字母全部大写,各单词之间用下划线隔开;要求各成员的第一个单词相同。命名举例:

typdef enum

{

LAPD_ MDL_ASSIGN_REQ,

LAPD_MDL_ASSIGN_IND,

LAPD_DL_DATA_REQ,

LAPD_DL_DATA_IND,

LAPD_DL_UNIT_DATA_REQ,

LAPD_DL_UNIT_DATA_IND,

} LAPD_PRMV_TYPE;

<规则6> 类的命名

前缀意义举例

C 类CMyClass

CO COM类COMMyObjectClass

CF COM class factory CFMyClassFactory

I COM interface class IMyInterface

CImpl COM implementation class CImplMyInterface

<规则7> 函数的命名

单词首字母为大写,其余均为小写,单词之间不用下划线。函数名应以一个动词开头,即函数名应类似摱:

void PerformSelfTest(void) ;

void ProcChanAct(MSG_CHAN_ACTIV *pMsg, UC MsgLen);

1.3 可维护性

<规则1> 在逻辑表达式中使用明确的逻辑判断。

示例:如下逻辑表达式不规范。

1) if ( strlen(strName) )

2) for ( index = MAX_SSN_NUMBER; index ; index -- )

3) while ( p && *p ) // 假设p为字符指针

应改为如下:

1) if ( strlen(strName) != 0 )

2) for ( index = MAX_SSN_NUMBER; index != 0 ; index -- )

3) while ((p != NULL) && (*p != '\0' ))

<规则2> 预编译条件不应分离一完整的语句。

不正确:

if (( cond == GLRUN)

#ifdef DEBUG

|| (cond == GLWAIT)

#endif

)

{

}

正确:

#ifdef DEBUG

if( cond == GLRUN || cond == GLWAIT )

#else

if( cond == GLRUN )

#endif

{

}

<规则3> 在宏定义中合并预编译条件。

不正确:

#ifdef EXPORT

for ( i = 0; i < MAX_MSXRSM; i++ )

#else

for ( i = 0; i < MAX_MSRSM; i++ )

#endif

正确:

头文件中:

#ifdef EXPORT

#define MAX_MS_RSM MAX_MSXRSM

#else

#define MAX_MS_RSM MAX_MSRSM

#endif

源文件中:

for( i = 0; i < MAX_MS_RSM; i++ )

<规则4> 使用宏定义表达式时,要使用完备的括号。如下的宏定义表达式都存在一定的隐患。

#define REC_AREA(a, b) a * b

#define REC_AREA(a, b) (a * b)

#define REC_AREA(a, b) (a) * (b)

正确的定义为:

#define REC_AREA(a, b) ((a) * (b))

<规则5> 宏所定义的多条表达式应放在大括号内。

示例:下面的语句只有宏中的第一条表达式被执行。为了说明问题,for语句的书写稍不符规范。#define INIT_RECT_VALUE( a, b ) \

a = 0 ; \

b = 0 ;

for ( index = 0 ; index < RECT_TOTAL_NUM ; index ++ )

INIT_RECT_VALUE( rect.a, rect.b ) ;

正确的用法应为:

#define INIT_RECT_VALUE( a, b ) \

{ \

a = 0 ; \

b = 0 ; \

}

for ( index = 0 ; index < RECT_TOTAL_NUM ; index ++ )

{

INIT_RECT_VALUE( rect[ index ].a, rect[ index ].b ) ;

}

<规则6> 宏定义不能隐藏重要的细节,避免有return,break等导致程序流程转向的语句。如下例子是不规范的应用,其中隐藏了程序的执行流程。

#define FOR_ALL for(i = 0; i < SIZE; i++)

/* 数组c 置0 */

FOR_ALL

{

c[i] = 0;

}

#define CLOSE_FILE { \

fclose(fp_local); \

fclose(fp_urban); \

return; \

}

<规则7> 使用宏时,不允许参数发生变化。

下面的例子隐藏了重要的细节,隐含了错误。

#define SQUARE ((x) * (x))

.

.

.

w = SQUARE(++value);

这个引用将被展开称:

w = ((++value) * (++value));

其中value累加了两次,与设计思想不符。正确的用法是:

w = SQUARE(x);

x++;

<规则8> 当if、while、for等语句的程序块为摽諗时,使用搟}敺_ while ( *s++ == *t++ ) ;

以上代码不符合规范,正确的书写方式为:

while( *s++ == *t++ )

{

/* 无循环体*/

}

while( *s++ == *t++ )

{

}

<规则9> 结构中元素布局合理,一行只定义一个元素。

如下例子不符合规范,

typedef struct

{

_UI left, top, right, bottom;

} RECT;

应书写称:

typedef struct

{

_UI left; /* 矩形左侧x 坐标*/

_UI top;

_UI right;

_UI bottom;

} RECT;

<规则10> 枚举值从小到大顺序定义。

<规则11> 包含头文件时,使用撓喽月肪稊,不使用摼

如下引用:

#include "c:\switch\inc\def.inc"

应改为:

#include "inc\def.inc"

#include "def.inc"

<规则12> 不允许使用复杂的操作符组合等。

下面用法不好,

iMaxVal = ( (a > b ? a : b) > c ? (a > b ? a : b) : c );

应该为:

iTemp = ( a > b ? a : b);

iMaxVal = (iTemp > b ? iTemp : b);

不要把"++"、"--"操作符与其他如"+="、"-="等组合在一起形成复杂奇怪的表达式。如下的表达式那以理解。

*pStatPoi++ += 1;

*++pStatPoi += 1;

应分别改为:

*pStatPoi += 1;

pStatPoi++;

++pStatPoi;

*pStatPoi += 1;

<规则13> 函数和过程中关系较为紧密的代码尽可能相邻。

如初始化代码应放在一起,不应在中间插入实现其它功能的代码。以下代码不符合规范,

for (uiUserNo = 0; uiUserNo < MAX_USER_NO; uiUserNo++)

{

...; /* 初始化用户数据*/

}

pSamplePointer = NULL;

g_uiCurrentUser = 0; /* 设置当前用户索引号*/

应必为:

for (uiUserNo = 0; uiUserNo < MAX_USER_NO; uiUserNo++)

{

...; /* 初始化用户数据*/

}

g_uiCurrentUser = 0; /* 设置当前用户索引号*/

pSamplePointer = NULL;

<规则14> 每个函数的源程序行数原则上应该少于200行。

对于消息分流处理函数,完成的功能统一,但由于消息的种类多,可能超过200行的限制,不属于违反规定。

<规则15> 语句嵌套层次不得超过5层。

嵌套层次太多,增加了代码的复杂度及测试的难度,容易出错,增加代码维护的难度。

<规则16> 用sizeof来确定结构、联合或变量占用的空间。

这样可提高程序的可读性、可维护性,同时也增加了程序的可移植性。

<规则17> 避免相同的代码段在多个地方出现。

当某段代码需在不同的地方重复使用时,应根据代码段的规模大小使用函数调用或宏调用的方式代替。这样,对该代码段的修改就可在一处完成,增强代码的可维护性。

<规则18> 使用强制类型转换。

示例:

USER_RECORD *pUser;

pUser = (USER_RECORD *) malloc (MAX_USER * sizeof(USER_RECORD));

<规则19> 避免使用goto 语句。

<规则20> 避免产生摮绦蚪釘(program knots),在循环语句中,尽量避免break、goto的使用。

如下例子:

for( i = 0; i < n; i++)

{

bEof = fscanf( pInputFile, "%d;", &x[i]);

if( bEof == EOF )

{

break;

}

nSum += x[i];

}

最好按以下方式书写,避免程序打摻釘:

for( i = 0; i < n && bEof= EOF; i++)

{

bEof = fscanf( pInputFile, "%d;", &x[i]);

if( bEof!= EOF )

{

nSum += x[i];

}

}

<规则21> 功能相近的一组常量最好使用枚举来定义。

不推荐定义方式:

/* 功能寄存器值*/

#define ERR_DATE 1 /* 日期错误*/

#define ERR_TIME 2 /* 时间错误*/

#define ERR_TASK_NO 3 /* 任务号错误*/

推荐按如下方式书写:

/*功能寄存器值*/

enum ERR_TYPE

{

ERR_DATE = 1, /*日期错误*/

ERR_TIME = 2, /*时间错误*/

ERR_TASK_NO = 3 /* 任务号错误*/

}

<规则22> 每个函数完成单一的功能,不设计多用途面面俱到的函数。

多功能集于一身的函数,很可能使函数的理解、测试、维护等变得困难。

使函数功能明确化,增加程序可读性,亦可方便维护、测试。

<建议1> 循环、判断语句的程序块部分用花括号括起来,即使只有一条语句。

如:

if( bCondition == TRUE )

bFlag = YES;

建议按以下方式书写:

if( bCondition == TRUE )

{

bFlag = YES;

}

这样做的好处是便于代码的修改、增删。

<建议2> 一行只声明一个变量。

不推荐的书写方式:

void DoSomething(void)

{

int Amicrtmrs, nRC;

int nCode, nStatus;

推荐做法:

void DoSomething(void)

{

int nAmicrtmrs; /* ICR 计时器*/

int nRC; /* 返回码*/

int nCode; /* 访问码*/

int nStatus; /* 处理机状态*/

<建议3> 使用专门的初始化函数对所有的公共变量进行初始化。

<建议4> 使用可移植的数据类型,尽量不要使用与具体硬件或软件环境关系密切的变量。<建议5> 用明确的函数实现不明确的语句功能

示例:如下语句的功能不很明显。

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 ) ;

1.4. 程序正确性、效率

<规则1> 严禁使用未经初始化的变量。

引用未经初始化的变量可能会产生不可预知的后果,特别是引用未经初始化的指针经常会导致系统崩溃,需特别注意。声明变量的同时初始化,除了能防止引用未经初始化的变量外,还可能生成更高效的机器代码。

<规则2> 定义公共指针的同时对其初始化。

这样便于指针的合法性检查,防止应用未经初始化的指针。建议对局部指针也在定义的同时初始化,形成习惯。

<规则3> 较大的局部变量(2K以上)应声明成静态类型(static),避免占用太多的堆栈空间。

避免发生堆栈溢出,出现不可预知的软件故障。

<规则4> 防止内存操作越界。

说明:内存操作主要是指对数组、指针、内存地址等的操作。内存操作越界是软件系统主要错误之一,后果往往非常严重,所以当我们进行这些操作时一定要仔细小心。

A.数组越界。

char aMyArray[10];

for( i = 0; i <= 10; i++ )

{

aMyArray[i] = 0; //当i等于10时,将发生越界。

}

B.指针操作越界。

char aMyArray[10];

char *pMyArray;

pMyArray = aMyArray;

--pMyArray; // 越界

pMyArray = aMyArray;

pMyArray += 10; // 越界

<规则5> 减少没必要的指针使用,特别是较复杂的指针,如指针的指针、数组的指针,指针的数组,函数的指针等。

用指针虽然灵活,但也对程序的稳定性造成一定威胁,主要原因是当要操作一个指针时,此指针可能正指向一个非法的地址。安安全全地使用一个指针并不是一件容易的事情。

<规则6> 防止引用已经释放的内存空间。

在实际编程过程中,稍不留心就会出现在一个模块中释放了某个内存块(如指针),而另一模块在随后的某个时刻又使用了它。要防止这种情况发生。

<规则7> 程序中分配的内存、申请的文件句柄,在不用时应及时释放或关闭。

分配的内存不释放以及文件句柄不关闭,是较常见的错误,而且稍不注意就有可能发生。这类错误往往会引起很严重后果,且难以定位。

<规则8> 注意变量的有效取值范围,防止表达式出现上溢或下溢。

示例:

unsigned char cIndex = 10;

while( cIndex-- >= 0 )

{

} //将出现下溢

当cIndex等于0 时,再减1不会小于0,而是0xFF,故程序是一个死循环。

char chr = 127;

chr += 1; //127为chr的边界值,再加1将使chr上溢到-128,而不是128。

<规则9> 防止精度损失。

以下代码将产生精度丢失。

#define DELAY_MILLISECONDS 10000

char time;

time = DELAY_MILLISECONDS;

WaitTime( time );

代码的本意是想产生10秒钟的延时,然而由于time为字符型变量,只取DELAY_MILLISECONDS 的低字节,高位字节将丢失,结果只产生了16毫秒的延时。

<规则10> 防止操易混淆的作符拼写错误。

形式相近的操作符最容易引起误用,如C/C++中的“=斢霌==敗|斢霌||敗&斢霌&&數龋

_

示例:如把“&斝闯蓳&&敚_

bRetFlag = ( pMsg -> bRetFlag & RETURN_MASK ) ;

被写为:

bRetFlag = ( pMsg -> bRetFlag && RETURN_MASK ) ;

<规则11> 使用无符号类型定义位域变量。

示例:

typedef struct

{

int bit1 : 1;

int bit2 : 1;

int bit3 : 1;

} bit;

bit.bit1 = 1;

bit.bit2 = 3;

bit.bit3 = 6;

printf("%d, %d, %d", bit.bit1, bit.bit2, bit.bit3 );

输出结果为:-1,-1, -2,不是: 1,3,6.

<规则12> switch语句的程序块中必须有default语句。

对不期望的情况(包括异常情况)进行处理,保证程序逻辑严谨。

<规则13> 当声明用于分布式环境或不同CPU间通信环境的数据结构时,必须考虑机器的字节顺序,使用的位域也要有充分的考虑。

比如Intel CPU与68360 CPU,在处理位域及整数时,其在内存存放的撍承驍,正好相反。

示例:假如有如下短整数及结构。

unsigned short int exam ;

typedef struct _EXAM_BIT_STRU

{ /* Intel 68360 */

unsigned int A1 : 1 ; /* bit 0 2 */

unsigned int A2 : 1 ; /* bit 1 1 */

unsigned int A3 : 1 ; /* bit 2 0 */

} _EXAM_BIT ;

如下是Intel CPU生成短整数及位域的方式。

内存: 0 1 2 ... (从低到高,以字节为单位)

exam exam低字节exam高字节

内存: 0 bit 1 bit 2 bit ... (字节的各撐粩)

_EXAM_BIT A1 A2 A3

如下是68360 CPU生成短整数及位域的方式。

内存: 0 1 2 ... (从低到高,以字节为单位)

exam exam高字节exam低字节

内存: 0 bit 1 bit 2 bit ... (字节的各撐粩)

_EXAM_BIT A3 A2 A1

<规则14> 编写可重入函数时,应注意局部变量的使用(如编写C/C++语言的可重入函数时,应使用auto即缺省态局部变量或寄存器变量)。

可重入性是指函数可以被多个任务进程调用。在多任务操作系统中,函数是否具有可重入性是非常重要的,因为这是多个进程可以共用此函数的必要条件。另外,编译器是否提供可重入函数库,与它所服务的操作系统有关,只有操作系统是多任务时,编译器才有可能提供可重入函数库。如DOS下BC和MSC 等就不具备可重入函数库,因为DOS是单用户单任务操作系统。

编写C/C++语言的可重入函数时,不应使用static局部变量,否则必须经过特殊处理,才能使函数具有可重入性。

<规则15> 编写可重入函数时,若使用全局变量,则应通过关中断、信号量(即P、V操作)等手段对其加以保护。

<规则16> 结构中的位域应尽可能相邻。结构中的位域在开始处应对齐撟纸跀或撟謹的边界。

这样可减少结构占用的内存空间,减少CPU处理位域的时间,提高程序效率。

示例:如下结构中的位域布局不合理。(假设例子在Intel CPU环境下)

typedef struct _EXAMPLE_STRU

{

unsigned int nExamOne : 6 ;

unsigned int nExamTwo : 3 ; // 此位域跨越字节摻唤訑处。

unsigned int nExamThree : 4 ;

} _EXAMPLE ;

应改为如下(按字节对齐)。

typedef struct _EXAMPLE_STRU

{

unsigned int nExamOne : 6 ;

unsigned int nFreeOne : 2 ; // 保留bit位,使下个位域从字节开始。

unsigned int nExamTwo : 3 ; // 此位域从新的字节处开始。

unsigned int nExamThree : 4 ;

} _EXAMPLE ;

<规则17> 避免函数中不必要语句,防止程序中的垃圾代码,预留代码应以注释的方式出现。

程序中的垃圾代码不仅占用额外的空间,而且还常常影响程序的功能与性能,很可能给程序的测试、维护等造成不必要的麻烦。

<规则18> 通过对系统数据结构的划分与组织的改进,以及对程序算法的优化来提高空间效率。

这种方式是解决软件空间效率的根本办法。

示例:如下记录学生学习成绩的结构不合理。

typedef unsigned char _UC ;

typedef unsigned int _UI ;

typedef struct _STUDENT_SCORE_STRU

{

_UC szName[ 8 ] ;

_UC cAge ;

_UC cSex ;

_UC cClass ;

_UC cSubject ;

float fScore ;

} _STUDENT_SCORE ;

C语言注释规范

C语言注释规范 1.注释原则 同一软件项目开发中,尽量保持代码注释规范和统一。 注释方便了代码的阅读和维护。 边写代码边注释,修改代码时要相应修改注释,保证注释和代码的一致性。 注释要简洁明确,不要出现形容词。 对于写的好的注释,我们将是第一个受益者。 大型软件开发中,通过别人的注释可以快速知道他人所写函数的功能,返回值,参数的使用。 2.文件头部的注释 示例: / * Program Assignment : 该文件的作用 * Author: 作者 * Date: 2013/8/6 14:34 * Description: 该文件的描述 *****/ /* * Source code in : 源代码的路径 * Function List: * initLinear 初始化线性表 * destoryLinear 释放线性表申请的空间 * isLinearEmpty 判断线性表是否为空 * isLinearFull 判断线性表是否为满 * getLinearElementValue 取得下标为index的元素的值 */ 注意:这个函数列表可以快速查询到我们想要了解的函数。 3.结构体,全局变量等的注释 示例: typedef POLYNOMIAL USER_TYPE; /* 新的数据类型的描述*/ int a; /* 全局变量的作用*/ /* 说明结构体的功能*/ typedef struct LINEAR { USER_TYPE *data; /* 每个成员的意义(作用) */ int maxRoom; /* 每个成员的意义(作用) */

int elementCount; /* 每个成员的意义(作用) */ }LINEAR; 4.函数的注释 在逻辑性较强的的地方加入注释,以便其他人的理解,在一定的程度上排除bug。 示例: /* * Function Name: getLinearElementIndex * Purpose: 取得元素的index值 * Params : * @LINEAR linear 线性表实例 * @USER_TYPE var 类型为USER_TYPE的实例 * @int (*)() cmp 提供接口,让用户定义具体比较函数 * Return: int 返回元素的index值 * Limitation: 如果返回-1,则代表不存在var的元素 */ int getLinearElementIndex(LINEAR linear, USER_TYPE var, int (*cmp)()) { /* * 如果逻辑太过复杂,这里写明该算法的过程和思路。 */ boolean found = FALSE; int i; for(i = 0; i < && !found; i++) if(cmp[i], var) == 0) found = TRUE; if(i >= i = NOT_FOUND; return i; }

程序代码注释编写规范

百度文库- 让每个人平等地提升自我 1 程序代码注释编写规范 为提高控制程序的阅读性与可理解性,现制定相关代码程序代码注释编写的编写规范。 一般情况下,源程序有效注释量必须在20%以上,注释的原则是有助于对程序的阅读理解,在该加的地方都加了,注释不宜太多也不能太少,注释语言必须准确、易懂、简洁。 常规注释有以下两种方式。 单行:以"文件、.inc文件、.def文件、编译说明文件.cfg等)头部应进行注释,注释必须列出:版权说明、版本号、生成日期、作者、内容、功能、与其它文件的关系、修改日志等,头文件的注释中还应有函数功能简要说明。 示例:下面这段头文件的头注释比较标准,当然,并不局限于此格式,但上述信息建议要包含在内。 /************************************************* (C), MicTiVo International. Co., Ltd. 1.File : . History: Date: Author: Modification: 2. .. *************************************************/ 一、源文件头 源文件头部应进行注释,列出:版权说明、版本号、生成日期、作者、模块目的/功能、主要函数及其功能、修改日志等。 示例:下面这段源文件的头注释比较标准,当然,并不局限于此格式,但上述信息建议要包含在内。 /************************************************************ (C), MicTiVo International. Co., Ltd. FileName: Author: Version : Date: : / /*receive _process() */ 意:与溢出中断写初值不同}

C语言编码规范

C语言编程规范 对于程序员来说,能工作的代码并不等于“好”的代码。“好”代码的指标很多,包括易读、易维护、易移植和可靠等。其中,可靠性对嵌入式系统非常重要,尤其是在那些对安全性要求很高的系统中,如飞行器、汽车和工业控制中。这些系统的特点是:只要工作稍有偏差,就有可能造成重大损失或者人员伤亡。一个不容易出错的系统,除了要有很好的硬件设计(如电磁兼容性),还要有很健壮或者说“安全”的程序。 然而,很少有程序员知道什么样的程序是安全的程序。很多程序只是表面上可以干活,还存在着大量的隐患。当然,这其中也有C语言自身的原因。因为C语言是一门难以掌握的语言,其灵活的编程方式和语法规则对于一个新手来说很可能会成为机关重重的陷阱。同时,C语言的定义还并不完全,即使是国际通用的C语言标准,也还存在着很多未完全定义的地方。要求所有的嵌入式程序员都成为C语言专家,避开所有可能带来危险的编程方式,是不现实的。最好的方法是有一个针对安全性的C语言编程规范,告诉程序员该如何做。 本规范在制定过程中,主要参考了业界比较推崇的《华为软件编程规范和范例》和《MI SRA 2004规则》,适合C语言初学者使用,目的在于在教学中培养学生良好的编程规范和意识、素质,促进所设计程序安全、健壮、可靠、可读与可维护(程序简单、清晰)。考虑到面向的是初学者,为便于教学和课程考核操作,本规范中的要求比较基本。事实上,很多公司都有自己规定的代码风格,包括命名规则、缩进规则等,学生参加工作后,应再进一步学习和应用公司的规范。 建议学生在学习本规范的同时,花点时间阅读本规范的参考文献原文,特别是熟读本规范的参考文献之一的《“安全第一”的C语言编程规范》,深刻理解编程规范与程序安全、健壮、可靠、可读、可维护间的关系和作用,在学习和工作中养成良好的编程风格。 1 排版 1.1 严格采用阶梯层次组织程序代码 函数或过程的开始、结构的定义及循环、判断等语句中的代码都要采用缩进风格,case 语句下的情况处理语句也要遵从语句缩进要求。 程序块的分界符(如C/C++ 语言的大括号‘{’和‘}’)应各独占一行并且位于同一列,同时与引用它们的语句左对齐。在函数体的开始、类的定义、结构的定义、枚举的定义以及if 、for 、do 、while 、switch 、case 语句中的程序都要采用如上的缩进方式。 各层次缩进的风格采用TAB缩进(TAB宽度原则上使用系统默认值,TC使用8空格宽度,VC使用4空格宽度)。示例:

编码规范考试题答案

一、单选题 1. 如下关于集合类的描述错误的是B A. 含有集合意义的属性命名,尽量包含其复数的意义 B. 集合中的数据不需要释放,垃圾回收器会自动回收 C. 集合必须指定模板类型 D. 使用集合类时要设置初始化容量 2. 关于线程以下说法错误的有B A. 新起一个线程,都要使用(“…”)设置线程名 B. 在或更新的版本中,若字符串拼接发生在单线程环境,使用StringBuffer C. 对多线程访问的变量、方法,必须加锁保护,避免出现多线程并发访问引起的问题 D. 线程使用时,要在代码框架中使用线程池,避免创建不可复用的线程;禁止在循环中创建新线程,否则会引起JVM资源耗尽 3. 下面哪个是推荐使用的对称密码算法B A. DES B. AES C. SHA D. RSA 4. 以下说法正确的有C A. 程序中的一些状态多直接用数字表示,如函数执行成功return 1 B. 对于表示函数执行错误,多用约定的错误码来标识 C. 用有意义的静态变量或者枚举来代替数字型的程序状态,如函数执行成功return SUCCESS D. 程序中的魔鬼数字并不可怕,需要所有开发人员努力理解这些数字的含义 5. 下列错误使用异常的做法是D A. 在程序中使用异常处理还是使用错误返回码处理,根据是否有利于程序结构来确定,并且异常和错误码不应该混合使用,推荐使用异常 B. 一个方法不应抛出太多类型的异常。throws/exception子句标明的异常最好不要超过三个 C. 异常捕获尽量不要直接 catch (Exception ex),应该把异常细分处理 D. 程序内抛出的异常本身就可说明异常的类型、抛出条件,可不填写详细的描述信息。捕

C 代码规范

C#代码规范 1、前言 本文档定义了一些通用的代码规范和准则,一般情况下本文档适用于项目组所有项目,特殊情况下,如果客户有自己的代码规范,以客户的代码优先。 2、大小写约定 2.1、大小写样式,本文中将出现两种大小写样式,这里先分别定义: Pascal大小写 将标识符的首字母和后面连接的每个单词的首字母都大写。可以对三字符或更多字符的标识符使用Pascal大小写。例如:BackColor Camel大小写 标识符的首字母小写,而每个后面连接的单词的首字母都大写。例如:backColor 匈牙利命名法 基本原则是:变量名=属性+类型+对象描述。例如:lblName 2.2、标识符大小写规则 2.2.1、下表中列出常见的代码元素的样式规范和示例

2.2.2、除了遵循以上大小写约定外还需注意以下约定(除常量为特例): ?如果标识符由多个单词组成,请不要在各单词之间使用分隔符,如下划线(“_”)或连字符(“-”)等。而应使用大小写来指示每个单词的开头。 ?所有公共的成员如:方法、属性,都应使用Pascal大小写样式 2.3、首缩写词的大小写规则 2.3.1、首字母缩写词 首字母缩写词是由术语或短语中各单词的首字母构成的单词。 例如,HTML是HypertextMarkupLanguage的首字母缩写。为了方便编码规范的实施,本文规定受字母缩写词必须至少为两个单词,正好为两个单词的首字母缩写词称其为“短型首字母缩写词”,两个单词以上的称其为“长型首字母缩写词”

2.3.2、单缩写词 单缩写词是一个单词的缩写。例如,ID是identifier的缩写。 注意:可在标识符中使用的两个缩写词是ID和OK。在采用Pascal大小写格式的标识符中,这两个缩写词的大小写形式应分别为Id和Ok。如果在采用大小写混合格式的标识符中将这两个缩写词用作首个单词,则它们的大小写形式应分别为id和ok。 2.3.3、首字母缩写词有以下大小写规则: 短型首字母缩写词在Pascal大小写样式中,两个字母都应大写。在Camel 大小写样式中,如果是首个单词,两个字母都应小写。例如: ?名为DBRate的属性是一个采用Pascal大小写格式的标识符,它使用短型首字母缩写词(DB)作为首个单词。 ?名为ioChannel的参数是一个采用大小写混合格式的标识符,它使用短型首字母缩写词(IO)作为首个单词。 长型首字母缩写词,在任何大小写样式中都视为一个单词。例如: ?名为XmlWriter的类是一个采用Pascal大小写格式的标识符,它使用长型首字母缩写词作为首个单词。 ?名为htmlReader的参数是一个采用大小写混合格式的标识符,它使用长型首字母缩写词作为首个单词。 2.3.4、复合词的大小写规则: 所有复合词在任何大小写样式中都视为一个完整单词。 例如,hashtable是一个紧凑格式的复合词,应将其视为一个单词并相应地确定大小写。如果采用Pascal大小写格式,则该复合词为Hashtable;如果采用大小写混合格式,则该复合词为hashtable。若要确定某个单词是否是紧凑格式的复合词,请查阅最新的词典。 2.3.5、区分大小写 大小写准则只是为了使标识符更易于阅读和辨认。不能将大小写规则用作避免库元素之间的命名冲突的手段。 3、通用命名约定

国家标准代号

国家标准代号 序号代号含义管理部门 1 GB 中华人民共和国强制性国家标准国家标准化管理委员会 2 GB/T 中华人民共和国推荐性国家标准国家标准化管理委员会 3 GB/Z 中华人民共和国国家标准化指导性技术文件国家标准化管理委员会 行业标准代号 序号代号含义主管部门 1 BB 包装中国包装工业总公司包改办 2 CB 船舶国防科工委中国船舶工业集团公司、中国船舶重工集团公司(船舶) 3 CH 测绘国家测绘局国土测绘司 4 CJ 城镇建设建设部标准定额司(城镇建设) 5 CY 新闻出版国家新闻出版总署印刷业管理司 6 DA 档案国家档案局政法司 7 DB 地震国家地震局震害防预司 8 DL 电力中国电力企业联合会标准化中心 9 DZ 地质矿产国土资源部国际合作与科技司(地质) 10 EJ 核工业国防科工委中国核工业总公司(核工业) 11 FZ 纺织中国纺织工业协会科技发展中心 12 GA 公共安全公安部科技司 13 GY 广播电影电视国家广播电影电视总局科技司 14 HB 航空国防科工委中国航空工业总公司(航空)

16 HJ 环境保护国家环境保护总局科技标准司 17 HS 海关海关总署政法司 18 HY 海洋国家海洋局海洋环境保护司 19 JB 机械中国机械工业联合会 20 JC 建材中国建筑材料工业协会质量部 21 JG 建筑工业建设部(建筑工业) 22 JR 金融中国人民银行科技与支付司 23 JT 交通交通部科教司 24 JY 教育教育部基础教育司(教育) 25 LB 旅游国家旅游局质量规范与管理司 26 LD 劳动和劳动安全劳动和社会保障部劳动工资司(工资定额) 27 LY 林业国家林业局科技司 28 MH 民用航空中国民航管理局规划科技司 29 MT 煤炭中国煤炭工业协会 30 MZ 民政民政部人事教育司 31 NY 农业农业部市场与经济信息司(农业) 32 QB 轻工中国轻工业联合会 33 QC 汽车中国汽车工业协会 34 QJ 航天国防科工委中国航天工业总公司(航天) 35 QX 气象中国气象局检测网络司 36 SB 商业中国商业联合会行业发展部 37 SC 水产农业部(水产)

C语言编程规范

编码规范 1. 头文件编码规范 (2) 2. 函数编写规范 (2) 3. 标识符命名与定义 (2) 3.1通用命名规则 (2) 3.2 变量命名规则 (3) 3.3函数命名规则 (3) 3.4 宏的命名规则 (3) 4. 变量 (3) 5. 宏、常量 (4) 6. 质量保证 (4) 7. 程序效率 (5) 8. 注释 (5) 9. 排版与格式 (6) 10. 表达式 (7) 11. 代码编辑、编译 (7) 12. 安全性 (7) 13. 可读性 (7) 14. 可测性 (7) 15. 单元测试 (8) 16. 可移植性 (8)

1. 头文件编码规范 1. 禁止头文件循环依赖。 2. .c/.h文件不要包含用不到的头文件。 3. 禁止在头文件中定义变量。 4. 同一产品统一包含头文件排列方式。(如功能块排序、文件名升序、稳定度排序。) 5. 只能通过包含头文件的方式使用其他.c提供的接口,禁止在.c中通过extern的方式使用外部函数接口、变量。 2. 函数编写规范 1. 一个函数仅完成一件功能。 2. 重复代码应该尽可能提炼成函数。 3.为简单功能编写函数 4.函数的返回值要清楚、明了,让使用者不容易忽视错误情况。 5. 避免函数过长,新增函数不超过100行(非空非注释行)。 6. 避免函数的代码块嵌套过深,新增函数的代码块嵌套不超过4层。 7. 可重入函数应避免使用全局变量和禁止使用static变量。 8. 设计高扇入,合理扇出(小于7)的函数。 9. 废弃代码(没有被调用的函数和变量)要及时注释(有助于更好理解程序)。 10. 对所调用函数的错误返回码要仔细、全面地处理。 11. 函数不变参数使用const。 12. 函数应避免使用全局变量、静态局部变量和I/O操作,不可避免的地方应集中使用。 13. 函数的参数个数不超过5个。 14. 减少或禁止函数本身或函数间的递归调用 3. 标识符命名与定义 3.1通用命名规则 1. 标识符的命名要清晰、明了,有明确含义,同时使用完整的单词或大家基本可以理解的缩写,避免使人产生误解。 2. 除了常见的通用缩写以外,不使用单词缩写,不得使用汉语拼音。 示例: argument 可缩写为arg buffer 可缩写为buff clock 可缩写为clk command 可缩写为cmd compare 可缩写为cmp configuration 可缩写为cfg device 可缩写为dev error 可缩写为err hexadecimal 可缩写为hex increment 可缩写为inc initialize 可缩写为init maximum 可缩写为max message 可缩写为msg minimum 可缩写为min parameter 可缩写为para

程序的书写规则(程序的编码规范)

程序的书写规则(程序的编码规范) 随着软件产品的功能增加和版本的提高,代码越来越复杂,源文件也越来越多,对于软件开发人员来说,除了保证程序运行的正确性和提高代码的运行效率之外,规范风格的编码会对软件的升级、修改、维护带来极大的方便性,也保证程序员不会陷入“代码泥潭”中无法自拔。开发一个成熟的软件产品,除了有详细丰富的开发文档之外,必须在编写代码的时候就有条不紊,细致严谨。 以下的编码规范包含了程序排版、注释、命名、可读性、变量、程序效率、质量保证、代码编译、代码测试和版本控制等注意事项。 一、排版: 1.关键词和操作符之间加适当的空格。 2.相对独立的程序块与块之间加空行 3.较长的语句、表达式等要分成多行书写。 4.划分出的新行要进行适应的缩进,使排版整齐,语句可读。 5.长表达式要在低优先级操作符处划分新行,操作符放在新行之首。 6.循环、判断等语句中若有较长的表达式或语句,则要进行适应的划分。 7.若函数或过程中的参数较长,则要进行适当的划分。 8.不允许把多个短语句写在一行中,即一行只写一条语句。 9.函数或过程的开始、结构的定义及循环、判断等语句中的代码都要采用缩进风 格。 10.C/C 语言是用大括号‘{’和‘}’界定一段程序块的,编写程序块时‘{’和 ‘}’应各独占一行并且位于同一列,同时与引用它们的语句左对齐。在函数体的开始、类的定义、结构的定义、枚举的定义以及if、for、do、while、switch、case语句中的程序都要采用如上的缩进方式。

二、注释 1.注释要简单明了。 2.边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。 3.在必要的地方注释,注释量要适中。注释的内容要清楚、明了,含义准确,防 止注释二义性。保持注释与其描述的代码相邻,即注释的就近原则。 4.对代码的注释应放在其上方相邻位置,不可放在下面。 5.对数据结构的注释应放在其上方相邻位置,不可放在下面;对结构中的每个域 的注释应放在此域的右方;同一结构中不同域的注释要对齐。 6.变量、常量的注释应放在其上方相邻位置或右方。 7.全局变量要有较详细的注释,包括对其功能、取值范围、哪些函数或过程存取 它以及存取时注意事项等的说明。 8.在每个源文件的头部要有必要的注释信息,包括:文件名;版本号;作者;生 成日期;模块功能描述(如功能、主要算法、内部各部分之间的关系、该文件与其它文件关系等);主要函数或过程清单及本文件历史修改记录等。 9.在每个函数或过程的前面要有必要的注释信息,包括:函数或过程名称;功能 描述;输入、输出及返回值说明;调用关系及被调用关系说明等。 三、命名 1.较短的单词可通过去掉“元音”形成缩写; 2.较长的单词可取单词的头几发符的优先级,并用括号明确表达式的操作顺序, 避免使用默认优先级。 3.使用匈牙利表示法 四、可读性 1.避免使用不易理解的数字,用有意义的标识来替代。 2.不要使用难懂的技巧性很高的语句。

C语言编写规范之注释

1、头文件包含Includes 2、私有类型定义 Private typedef 3、私有定义Private define 4、私有宏定义 Private macro 5、私有变量 Private variables 6、私有函数原型Private function prototypes 7、私有函数Private functions 8、私有函数前注释 /****************************************************************************** * * Function Name : FSMC_NOR_Init * Description : Configures the FSMC and GPIOs to interface with the NOR memory. * This function must be called before any write/read operation * on the NOR. * Input : None * Output : None * Return : None ******************************************************************************* / 9、程序块采用缩进风格编写,缩进空格为4。 10、相对独立的程序块之间、变量说明之后必须加空行; 11、较长的字符(>80字符)要分成多行书写,长表达式要在低优先级操作符划分新行,操作符放在新行之首,新行要恰当缩进,保持排版整齐; 12、循环、判断等语句中若有较长的表达式或语句,则要进行适应的划分,长表达式要在低优先级操作符处划分新行,操作符放在新行之首; 13、若函数或过程中的参数较长,则要进行适当的划分。 14、不允许把多个短语句写在一行中,即一行只写一条语句。 15、if、for、do、while、case、switch、default等语句自占一行,且if、for、 do、while等语句的执行语句部分无论多少都要加括号{}。 16、对齐只使用空格键,不使用TAB键; 17、 函数或过程的开始、结构的定义及循环、判断等语句中的代码都要采用缩进风格,case 语句下的情况处理语句也要遵从语句缩进要求 18、 程序块的分界符(如C/C++语言的大括号‘{’和‘}’)应各独占一行并且位于同一 列,同时与引用它们的语句左对齐。在函数体的开始、类的定义、结构的定义、枚举的定义以 及if、for、do、while、switch、case语句中的程序都要采用如上的缩进方式。 19、 在两个以上的关键字、变量、常量进行对等操作时,它们之间的操作符之前、之后或

通用编码规范

通用编码规范 1.引言 本规范编制是为了指导程序员编码,其目的是: 1)改善软件的可读性,使程序员尽快而彻底地理解新的代码; 2)防止新接触本语言的人出于节省时间的需要,自创与组织成员不相容的一套风格; 3)防止新接触本语言的人一次次的犯同样的错误; 4)新加入的程序员可以很快的适应环境; 5)在一致的环境下,减少程序员犯错的机会。 2.编排风格约定 编排风格应遵循下列规定: 1)严格采用阶梯层次组织程序代码:各层次缩进的分格采用VC的缺省风格,即每层次缩进为4格。功能块、语句块的边界大括号一律独占一行,相匹配的大括号在同一列,对继行则要求再缩进4格; 2)对变量的定义,尽量位于函数的开始位置; 3)函数名之后不要留空格,紧跟左括号‘(’,以与关键字区别; 4)‘(’向后紧跟,‘)’、‘,’、‘;’向前紧跟,紧跟处不留空格; 5)‘,’之后要留空格,如Function(x, y, z)。如果‘;’不是一行的结束符号,其后要留空格,如for (initialization; condition; update); 6)赋值操作符、比较操作符、算术操作符、逻辑操作符、位域操作符,如“=”、“+=”“>=”、“<=”、“+”、“*”、“%”、“&&”、“||”、“<<”,“^” 等二元操作符的前后应当加空格;但是,对于表达式比较长的for语句和if语句,为了紧凑起见可以适当地去掉一些空格,如for (i=0; i<10; i++)和if ((a<=b) && (c<=d)); 7)一元操作符如“!”、“~”、“++”、“--”、“&”(地址运算符)等前后不加空格。“[]”、“.”、“->”等操作符前后不加空格; 8)修饰符*和&紧靠变量名。 9)各个大的功能块之间最好留一空行以及适当的注释; 10) if、for、do、while、switch、case、default等语句自占一行,且if、for、do、while 等语句的执行语句部分无论多少都要加括号{ },对“return语句” 不要求; 11)不允许把多个短语句写在一行中,即一行只写一条语句; 12)长表达式要在低优先级操作符处拆分成新行,操作符放在新行之首(以便突出操作符),拆分出的新行要进行适当的缩进,使排版整齐,语句可读; 13)对于switch…case…语句,break语句要放在{ }内。 3.界面设计约定 界面设计应遵循下列约定:

java代码规范要求(公司用-补充版)

代码规范要求 为保证我公司研发代码的规范性、可读性,特制定该代码规范: 1、代码应遵循国际java代码规范 2、代码中所有switch(param){case int:break;}中case 参数应该为在类开始时定义的字符串,以增加后续研发中的可读性。例:private final int company=0; switch(param){case company:break;}不允许出现case0,case1等字样。 3、在对数据库进行大量数据读取时,应采用jdbc方式读取。以增快响应速度,减少内存消耗。数据量超过万单位时必须采用jdbc读取数据库,且应分页读取数据库。 4、方法作用必须注释,方法中传递的参数应该有注释,全局变量,局部变量都应有注释,以说明变量的意义。如方法会被多次调用,或应对二次开发则应注明返回值例:return Boolean true成功false失败; 5、代码中应该采用try catch捕获异常,且应该处理常见异常。 6、代码呈现页面不能出现null字样。 7、代码测试应用及所需捕获异常或输出信息应该采用log4j 进行输出。杜绝出现System.out.println();字样 8、代码不应出现重复定义,同一方法不能多次调用数据库,

如一个方法中需要多次调用数据库则应拆分为两个或多个。 9、同一方法中代码量超过50行则应进行拆分。 10、代码应该采用format格式化。 11、代码已经提交或二次开发时,应注明修改时间修改人修改原因修改后提交参数的内容 12、在未进行实例化的参数判断是否为空时,应该null在前例:if(null!=param) 13、在判断变量是否为空时,尽量避免采用if else应采用Parame==null?”0”:parame;进行判断赋值 14、代码应遵循可读性原则,不能出现过于冗长的代码。 15、多次在不同类中反复调用且内容相同的方法,应该写到公用代码中进行调用。 16、已经失效,且不会被调用的代码应该注销、删除。 17、代码在未经测试时,不要进行提交,以免造成现调用的其他类出现错误。 18、项目的配置文档应该遵循规范格式,尽量增加注释。 19、页面中的js脚本应该具备可读性、增加注释。Js脚本的规范遵从国际js规范。 20、页面中提交的必要的变量参数应该有验证。 21、页面提交的信息或执行时间较长、页面上传文档时应该提示用户正在执行等字样。 22、页面ext的方法复写定义应该在项目中为唯一,不得出

代码安全性检测指导规范(参考Word)

应用安全性测试指导规范(草稿) 1. 进行应用安全性测试的场景 安全性测试的目的是验证集成在软件内的保护机制是否能够在实际环境中保护系统的安全性。 从严格意义上,应用系统的安全性将涉及到应用的设计、开发和部署这三个主要环节,因而理想化的应用安全性测试应是与整个软件开发过程紧密集成的,即在软件设计、开发、测试和部署的过程中动态检测程序代码的安全性,并在应用最终部署之后进行全面的安全性测评。只有将应用和代码安全的管理融入到应用开发、部署、运维的各环节中,才能确保应用系统的安全性。 在应用系统上线并进入运维阶段之后,也需要在维护性开发过程中进行类似的代码安全性测试,并在日常的应用维护过程中动态进行应用整体安全性的评测。 代码安全性作为应用安全性中的一个核心的内容,是保障代码开发安全性的一个重要的举措,在开发活动结束的节点上应重点加强。而应用开发完毕后的部署和运维环节中,还将涉及到应用系统整体安全性评估的其他内容(包括网络安全、操作安全、权限安全、数据安全等)。 应用安全性测试的相关文档应纳入项目管理和运维管理的文档管理体系。1.1 初期的应用安全性测试场景 在传统的软件开发管理模式中引入应用安全测试将需要一个逐步的过程,在初期建议在如下的应用场景下,对目标应用系统的安全性进行测试:

1.2 目标的应用安全性测试相关场景 而从更完整意义上的应用系统整个生命周期各阶段中,需要进行的应用系统安全性测试、评估的工作可大致规划如下(供参考):

2. 应用安全性测试的范围与内容 应用安全性测试的范围与内容,应包括如下几个方面:

3. 应用安全性验收的流程与方法3.1 应用安全性验收的流程 应用安全性验收的流程图如下:

项目开发规范性文档

项目开发规范性文档 一:作用 项目开发过程中为了增加程序的可读性和程序的健壮性,方便后期程序的调试和维护,所以需要在开发过程中统一技术规范 二:目录 1.系统框架中模块功能,文件目录和文件名的规范 2.程序代码中文件名类名变量名接口名等规范 3.代码的书写的规范 4.数据库中表名字段名数据类型等规范 三:详细内容 说明 常用的命名风格如下。 (1)Pascal风格:包含一到多个单词,每一个单词第一个字母大写,其他字母小写,其余字母均小写。例如:CollegeStudent、HelloWorld等。 (2)Camel风格:包含一到多个单词,第一个单词首字母小写,其余单词首字母大写,其他字母均小写。例如:name、gender、somePara等。 1.系统框架功能模块、文件目录和文件名的规范 (1)功能模块命名规范 数据访问层(DAL)——DataSet,与数据库打交道的唯一方式;位于最底层; 数据控制层(DCL)——直接与DataSet打交道,通过实体工厂类产生实体对象和数据访问层打交道 数据封装层(DPL)——BEAN 实体类;

业务逻辑层(BLL)——与业务有关的操作,以上三层多不与业务逻辑有关; 通用工具层(CTL)——与项目无关、可独立的类库。如DBControl,Exception等; 系统管理层(SysManeger)--系统管理常用接口比如系统日志系统版本系统信息等 数据访问接口层(IDataFactory)--数据访问层的抽象工厂接口 实体访问接口层(EntityFactory)--数据访问层的实体工厂类,即产生实体对象的实体工厂类 (2)文件目录的命名规范 images --项目图片的目录 styles --项目css文件的目录 javascript --项目中js文件的目录 template --项目模板文件的目录 subsystem --项目子系统或模块的目录(一般用因为名字来表示系统的模块) document --项目说明文档目录 database --项目数据库目录 (3)文件名的命名规范 a.文件名尽量用一个或多个英文单词来表示做到见面知意的效果比如:Index.aspx Default.aspx Product.aspx OrderList.aspx等 b.所有单词的首字母要大些 c.尽量不要使用下划线来连接多个单词 2.程序代码中的命名规范 (1)命名空间 命名空间命名采用Pascal风格,取名的一般规则如下。 CompanyName.TechnologyName 例如: Microsoft.Office MyCompany.NamingRule.Test 另外,需要用复数的时候要使用复数的名称空间名。例如,使用System.Collections 而不是System.Collection。但是,当遇到缩写形式时,通常不需要使用复数。例

标准C语言规范

C语言编码规范 1.文件、函数规范 根据功能划分文件。文件名与主控函数名相同;主控函数必须放在最前面;函数的长度一般不宜超过150行;文件长度不宜超过500行。标准的文件头格式如下: 函数名: 功能: 调用函数:所涉及的主要功能函数 调用参数:必须详细说明 返回值: 编写时间: 修改时间:修改时包含此项 2.命名规范 ①函数命名规范 以便于理解为原则,由一个或多个单词或单词缩写组合而成,单词首字母大写。 如AddItem(),GetInt(),FxaUp() ②变量命名规范 由变量类型为前缀,加上函数命名规范组合而成。具体前缀命名方法如下:sh------short, i------int, l------long, c------char, f------float, d------double, p------pointer 字符串数组也使用p标志 静态变量名前用s标志 数组变量名前用stru标志 全局变量使用前缀g_标志 如:dBalance,fInterest,pName, sCustomer,struPersonWang, g_iOperNo 3.书写规范 ⑴对齐原则 同一层次的语句必须左对齐。“{”和“}”必须独占一行。 ⑵缩进原则 不同层次的语句必须遵从缩进原则,一般缩进四个字符为宜,TAB值设为4。 Case后的语句(简短注释语句除外)应另起一行,且须与“:”相接。 ⑶分行书写原则 当行超过屏幕上的行时,应分行书写。 ⑷注释符要求 单行注释符使用“//”,多行注释符使用“/*……*/”,注释符必须遵从前面3条原则,“/*”应与“*/”对齐。 4.语法规范

编程规范课程试题A卷20070307

一. 判断题(共19题,每题2分,直接在括号内打“√”或“×”) (对)1、不允许把多个短语句写在一行中,即一行只写一条语句。 (对)2、如果编程工具提供将TAB键转换成空格键,对齐、缩进可以使用TAB 键,否则应使用空格键。 (对)3、数据结构声明(包括数组、结构、类、枚举等),如果其命名不是充分自注释的,必须加以注释。 (对)4、i,j,k只可以用作循环变量,不能用于其它局部变量。 (错)5、当一个表达式包含多个运算符时,应该尽量用默认优先级来保证表达式的运算顺序。 (对)6、由于引用了全局变量和静态局部变量的函数不方便重入,因此在实时系统编程中,应尽量减少对全局变量和静态局部变量的使用。 (错)7、应当尽可能设计功能全面、灵活的数据结构,以提高效率。 (错)8、结构中元素的排列不影响结构占用空间的大小。 (错)9、断言可以用来处理程序的任何错误情况。 (错)10、在一般应用的情况下,当前代码,处理一个1000条记录的结果只要2000毫秒。采用了新的处理机制,处理同样大小的结果只要1999毫秒,这种提高还是有重要意义的。 (对)11、提高代码效率应当保证软件系统的正确性、稳定性、可读性及可测性的前提下进行。 (错)12、内存操作越界可以通过测试发现,设计时不必过分关注. (对)13、对程序进行编译时,必须打开编译器的所有告警开关。 (对)14、用宏定义代替表达式时,要使用完备的括号,保证宏定义的完整性。 (对)15、单元测试开始要跟踪每一条语句,并观察数据流及变量的变化。不能进行单步跟踪的代码,要采用日志输出等形式,跟踪数据流和变量的变化; (对)16、一个函数仅完成一件功能。 (对)17、对参数输入和非参数输入都要检查有效性。 (错)18、应该设计高扇出、合理扇入的函数。 (错)19、应该为函数功能的扩展预留尽可能多的参数接口。 二、单项选择题(共17题,每题2分) ( D )1、下面哪条语句符合编程规范: (A) for (...) { ... // program code } (B) if (...) { ... // program code }

代码规范的重要性

代码规范比比皆是,但是很少有公司做好代码规范的。忍不住想谈谈代码规范的重要性,希望所有人都能够重视起来。而且,我相信,如果我们代码规范能够做好的话,且不说开发水平提高多少,至少我们也会有很多出色开源项目。 一、规范的代码可以促进团队合作 一个项目大多都是由一个团队来完成,如果没有统一的代码规范,那么每个人的代码必定会风格迥异。且不说会存在多个人同时开发同一模块的情况,即使是分工十分明晰的,等到要整合代码的时候也有够头疼的了。大多数情况下,并非程序中有复杂的算法或是复杂的逻辑,而是去读别人的代码实在是一件痛苦的事情。统一的风格使得代码可读性大大提高了,人们看到任何一段代码都会觉得异常熟悉。显然的,规范的代码在团队的合作开发中是非常有益而且必要的。 二、规范的代码可以减少bug处理 很多IT人士将程序员比做民工,这也的确非常的形象。就像刚才提到的,复杂的算法或逻辑只占项目中很小的比例,大多仅仅是垒代码的工作。可是越是简单,测试的bug反而是越多,而且是无穷无尽的bug。这里很大的程度上是由于代码不规范所致。 没有规范的对输入输出参数的规范,没有规范的异常处理,没有规范的日志处理等等,不但导致了我们总是出现类似空指针这样低级的bug而且还很难找到引起bug的原因。相反,在规范的开发中,bug不但可以有效减少,查找bug也变得轻而易举。 规范不是对开发的制约,而确实是有助于提高开发效率的。 三、规范的代码可以降低维护成本 随着我们项目经验的累积,会越来越重视后期维护的成本。而开发过程中的代码质量直接影响着维护的成本。因此,我们不得不从开发时便小心翼翼。 在第一点中曾提到,规范的代码大大提高了程序的可读性,几乎所有的程序员都曾做过维护的工作,不用多说,可读性高的代码维护成本必然会大大降低。 但是,维护工作不仅仅是读懂原有代码,而是需要在原有代码基础上作出修改。我们可以先想像没有统一风格的情况下,A完成开发以后,B进行维护加一段代码,过一段时间C又加一段代码。。。。。。直到有一天X看到那一大堆乱码想死的心都有了,维护也就进行不下去了。因此,统一的风格有利于长期的维护。 另外,好的代码规范会对方法的度量、类的度量以及程序耦合性作出约束。这样不会出现需要修改一个上千行的方法或者去扩展一个没有接口的类的情况。规范的代码对程序的扩展性提高,无疑也是对维护人员的一个奖励。 四、规范的代码有助于代码审查 我个人是比较赞同进行代码审查的,这样可以及时纠正一些错误,而且可以对开发人员的代码规范作出监督。团队的代码审查同时也是一个很好的学习机会,对成员的进步也是很有益的。但是,开发随意,加重的代码审查的工作量及难度,并且使得代码审查工作没有根据,浪费了大量的时间却收效甚微。 代码规范不仅使得开发统一,减少审查拿督,而且让代码审查有据可查,大大提高了审查效率和效果,同时代码审查也有助于代码规范的实施。一举多得,何乐而不为呢。 五、养成代码规范的习惯,有助于程序员自身的成长 即使明白代码规范的好处,但是有的迫于项目压力,有的因为繁琐的规范作出很多额外的工

c代码风格规范.

代码风格规范 0. 说明 请先阅读一篇搞笑文章——《说一说编程恶习》 本规范尚在完善中,随时更新。 代码风格以增强程序可读性和可维护性为目标,并非金科玉律。在满足可读性和可维护性的前提下,可以适当灵活。 代码风格的细节比较繁杂,这里不会一一给出,请多看示例代码来体会其精妙之处。 1. 注释 1. 程序中必须有清晰的注释; 2. 程序头部要有程序整体说明信息; 3. 每个函数(main除外)都要有注释说明该函数的功能,及其参数和返回 值的意义; 4. 每个变量都要有注释说明其用途(for 循环中的下标除外; 5. 代码中要有适当的注释说明代码段的功能。 2. 缩进 1. 缩进的宽度为4个字符,鼓励用空格缩进, tab亦可(但尽量避免两者混 用; 2. 凡函数、if、while、for、do-while、switch等都要使用缩进,具体形式 参考示例代码。

3. 标识符命名 1. 凡标识符的命名要尽量能直观反映该标识符的功能(如做到这一点,可免 去注释说明); 2. 标识符用英文命名,不可用汉语拼音; 3. 变量命名采用“variable_name”的形式; 4. 函数命名采用“FunctionName”的形式; 5. 宏、常量、枚举的命名采用“MACRO_NAME”的形式。 4. 空行及空格 1. 以增强可读性为目标,适当使用空行和空格; 2. 不可出现连续的两个及两个以上的空行; 3. 代码功能段之间用空行分隔; 4. 不在行尾的每个逗号和分号后要有一个空格; 5. 一般每个运算符前后都要有一个空格; 6. if, while, for, do, switch 和判断条件之间要有一个空格。 5. 其它 1. 左大括号“{”后不可出现代码; 2. 右大括号“}”前不可出现代码; 3. 每行只能写一条代码,且该行代码总长不可超过80个字符; 4. 常数应定义为宏、枚举或常量; 5. ……

国家重点XXXX项目--代码开发规范

附件四 国家发展改革委网上办公系统二期项目 代码开发规范 编制单位:北京AAAA信息产业股份有限公司 编制人: 编制日期:二○一一年四月

目录 第1章前言 (1) 1.1 目的 (1) 1.2 内容 (1) 1.3 定义 (2) 1.4 适用范围 (2) 第2章JAVA源码编写规范 (2) 2.1 标识符的命名规范 (2) 2.2 公认的命名约定 (3) 2.3 源文件注释的规范 (3) 2.3.1 Java中的注释类型 (3) 2.3.2 历史信息说明 (4) 2.3.3 类头部注释 (4) 2.3.4 变量常量注释 (5) 2.3.5 方法头部注释 (5) 2.3.6 代码注释 (5) 2.4 文档排版的规范 (6) 2.4.1 缩进 (6) 2.4.2 空格和空行 (6) 2.4.3 页面宽度 (7) 2.4.4 长参数表达式的换行 (7) 2.4.5 括号的匹配 (8) 2.4.6 import语句 (8) 第3章JSP源代码规范 (9) 3.1 页面目录结构 (9) 3.2 文件命名规范 (10) 3.3 HTML文件样式 (11) 3.4 使用标签代替Java编码 (12) 3.5 表单显示规范 (12) 3.6 缩进和对齐 (13) 3.7 注释 (14) 3.8 JavaScript文件 (14)

第1章前言 1.1 目的 为规范国家发展改革委网上办公系统二期项目(以下简称“发改委二期项目)系统的开发代码管理,特制定开发代码规范。通过该规范,我们希望达到以下目标: 1.增加开发过程代码的强壮性、可理解性、易维护性;减少有经验和无经验 开发人员编程所需的脑力工作; 2.在项目范围内统一代码风格; 3.使新的开发人员快速适应项目氛围; 4.更好的完成发改委二期项目的开发,以及后期的维护。 1.2 内容 本规范采用与国际代码规范基本一致的代码规范,并使得能在开发阶段将代码规范落实到项目组中的每一个有关人员。统一代码开发规范,提高代码的质量和可维护性。 提供事务、异常处理、文件处理等标准服务,规范各模块的处理方法。 制订代码开发规范,撰写核心代码规格及单元测试指针以建立测试导向的开发目标。 本规范包括对以下两个部分的规范要求:Java源文件和JSP源文件。将JSP 单独提出作为一部分加以规范,目的是为了让JSP源代码符合SUN提出的标准,而不是像一个Java文件。 规范主要分为以下几个个方面: 1.手工编写代码时需要注意的部分,如命名和注释; 2.代码排版时需要注意的部分,如缩进,换行等。这一部分可通过编辑器辅 助实现; 3.其它的一些问题,如某些技巧和常用解决方案。

相关文档
最新文档