-
软件开发规范
在
<
/p>
研究项目团队协作开发的情况下(这里的团队协作也适合于应用项目的
开发)
,
编程时应该强调的一个重要方面是程序的易读性,
在保证软件速度等性
能指标能满足
<
/p>
用户需求的情况下,能让其他程序员容易读懂你所编写的程序。
若
研究项目小组的所有开发人员都遵循统一的、
鲜明的一套编程风格,
可以让协
作者、后继者和自己
一
目了然,在很短的时间内看清楚程序结构,理解设计的
思路,大大提高代码的可读性、可
重用性、程序健壮性、可移植性、可维护性。
制定本编程规范
的目的是为了提高软件开发效率及所开发软件的可维护性,
提高软件的质量。本规范由程
序风格、命名规范、注释规范、程序健壮性、可移
植性、错误处理以及软件的模块化规范
等部分组成。
本软件开发规范适合讨论
C/C++
程序设计。
1
文件结构
每个
C++/C
程序通常分为两个文件。一个文件用于保存程序的声明
(
declaration
),称为头文件。另一个文件用
于保存程序的实现
(
implementation
),称为定义(
definition
)文件。<
/p>
C++/C
程序的头文件以“
.h
”为后缀,
C
程序
的定义文件以“
.c
”为后缀,
C++
程序的定义文件通常以“
.cpp
”为
后缀(也有一些系统以“
.cc
”或“
.cxx
”
为后缀)。
1.1
文件信息声明
文件信息声明位于头文件和定义文件的开头
(参见示例
1-1
)
,
主要内容有:
(
1
)
版权信息;
(
2
)
文件名称,项目代码,摘要,参考文献;
(
3
)
当前版本号,作者
/
修改者,完成日期
;
(
4
)
版本历史信息;
(
5
)
主要函数描述。
///////////////////////////
/////////////////////////////////////////
////////
////////////////////////////
////////////////////////////////////////
////////
// Copyright (c) 2004,
Department of Mathematics, Zhejiang University
// All rights reserved.
//
// Filename
:
filename.h
// Project Code
:
The project code about this
file
// Abstract
:
Describe the content of
this file summarily
//
Reference
:
......
//
// Version
:
1.1
// Author
:
the name of
author(mender)
//
Accomplished date
:
September 2, 2004
//
// Replaced version
:
1.0
//
Original Author :
the name of
original author(mender)
//
Accomplished date :
September 10,
2003
//
// Main
functions
:
//
Function 1 Return code
Function name(Parameter Explain)
//
Function 2 Return code
Function name(Parameter Explain)
//
...
//
Function n
Return code
Function name(Parameter
Explain)
//////////////////////////////
//////////////////////////////////////
/
///////
///////////////////////////////
/////////////////////////////////////
//
//////
示例
1-1
文件信息声明
☆
< br>【规则
1.1-1
】
文件信息声明以两行斜杠开始,
以两行斜杠结束,
每一行都
以两个斜杠开始;
☆
【规则
1.1-2
】
文件信息声明包含五个部分,各部分之间以一空行间隔;
☆
【规则
1.1-3
】
在主要函
数部分描述了文件所包含的主要函数的声明信息,
如果是头文件,这一部分是可以省略的
。
1.2
头文件的结构
头文件由三部分内容组成:
(1)
头文件开头处的文件信
息声明
(
参见示例
1-1)
;
(2)
预处理块;
(3)
函数和类结构声明等。
假设头文件名称为
filesystem.h
,头文件的结构参见示例
1-2
。
☆
【规则
1.2-1
】
< br>
为了防止头文件被重复引用,
应当用
< br>ifndef/define/endif
结构产生预处理块;“
#ifndef
”或者“
#define
”后以
TAB
键代替
SPA
CE
键做空格;如果头文件名称是由多个单词组
成,则各单词间
以下划线“
_
”连接,例如有头文件名称为
“
filesystem.h
”,则定义如下:“
#ifndef
_FILE_SYSTEM_H_
”;
☆
【规则
1.2-2
】
用
#include
格式来引用标准库的头文件
(
编译器将从标准库
目录开始搜索
)
;
☆
【规则
1.2-3
】
用
#include
“filename.h” 格式来引用非标准库的头文
件
p>
(
编译器将从用户的工作目录开始搜索
)<
/p>
;
☆
【建议
1.2-1
】
< br>
头文件中只存放“声明”而不存放“定义”;
☆
【建议
1.2-1
】
头文件中应
包含所有定义文件所定义的函数声明,
如果一个
头文件对应多个
定义文件,
则不同定义文件内实现的函数要
分开声明,
并作注释以解释所声明的函数从属于那一个定义
文件;
< br>
☆
【建议
p>
1.2-3
】
宏
定义和函数声明分离,
在两个头文件中定义,
如果没有类
成员函数,
可以将类和结构的定义与函数声明分离,
< br>也就是
说一个头文件专用于宏定义,
一个头文件专用于类
和结构的
定义,一个头文件专用于函数声明;
☆
【建议
1.2-4
】
在
C++
语法中,类的成员函数可以
在声明的同时被定义,
并且自动成为内联函数。
这虽然会带来书
写上的方便,
但却
造成了风格不一致,
弊大于利。
建议将成员函数的定义与声
明分开,不论该函数体有
多么小。
头文件的结构如下:
//
文件信息声明见示例
1-1
,此处省略。
#ifndef
repeat
#define
#include
…
#include
“myheader.h”
//reference non-standard head file
…
void
Function1(
…
);
//global function declare
//reference standard head file
_FILE_SYSTEM_H_
//avoid
referencing the file
filesystem.h
_FILE_SYSTEM_H_
…
class CBox
{
…
};
#endif
示例
1-2
C++/C
头文件的结构
//class structure
decalre
1.3
定义文件的结构
定义文件有三部分内容:
(1)
定义文件开头处的文件
信息声明
(
参见示例
1-1)
;
(2)
对一些头文件的引用;
(3)
程序的实现体(包括数据和代码)。
假设定义文件的名称为
filesystem.c
,定义文件的结构参见示例
1-3
。
//
文件信息声明见示例
1-1
,此处省略。
#include
“filesystem.h”
//reference a head file
…
//global function realization
void Function1(
…
)
{
…
}
//class member
function realization
void
CBox::Draw(
…
)
{
…
}
示例
1-3
C++/C
定义文件的结构
1.4
头文件的作用
早期的编程语言如
p>
Basic
、
Fortran
没有头文件的概念,
C++/C
语言的初学者
虽然会用使用头文件,但常常不明其理。这里对头文件的作用略作解释:
(
1
)
通过头文件来调用库功能。在很多场合,源代码不便(或不准)向用
户公布,
只要向用户提供头文件和二进制的库即可。
用户只
需要按照头
文件中的接口声明来调用库功能,
而不必关心接口怎
么实现的。
编译器
会从库中提取相应的代码;
< br>
(
2
)
p>
头文件能加强类型安全检查。如果某个接口被实现或被使用时,其方
式与头文件中的声明不一致,
编译器就会指出错误,
这一简单的
规则能
大大减轻程序员调试、改错的负担。
1.5
目录结构
< br>如果一个软件的头文件数目比较多(如超过十个),通常应将头文件和定义
文件分
别保存于不同的目录,以便于维护。
例如可将头文件保存于<
/p>
include
目录,将定义文件保存于
source
目录(可
以是多级目录)。
如果某些头文件是私有的,它不会被用户的程序直接引用,则没有必要公开
其“声明”。为了加强信息隐藏,这些私有的头文件可以和定义文件存放于同一
< br>个目录。
2
命名规则
比较著名的命名规则当推
“匈牙利”
命名法,
该命名规则的主要思想是
“在
变量和函数名中加入前缀以增进人们对程序的理解”
。
例如所有的字符变量均以
ch
为前缀,若是指针
变量则追加前缀
p
。如果一个变量由
p
pch
开头,则表明它
是指向字符指针的指针。
“匈牙利”法最大的缺点是烦琐,例如
int i, j, k;
float
x, y, z;
倘若采用“匈牙利”命名规则,则应当写成
int iI, iJ, ik; //
前缀
i
表示
int
类型
float fX,
fY, fZ; //
前缀
f
表示
float
类型
如此烦琐的程序会让绝大多数程序员无法忍受。
总的说来,没有一种命名规则可以让所有的程序员赞同,且命名规则对软件
产
品而言并不是
“成败悠关”
的事,
而且
在不同的平台和不同的环境下编写的程
序所应遵循的规则也不尽相同,
< br>所以我们只是追求制定一种令大多数项目成员满
意的命名规则,并在项目中贯彻实
施。
2.1
共性原则
本节论述的共性规则是被大
多数程序员采纳的,
我们应当在遵循这些共性规
则的前提下,再
扩充特定的规则,如
2.2
节
☆
【规则
2.1-1
】
< br>
标识符应当直观且可以拼读,
可望文知意,
不必进行
“解码”
;
☆
【规则
2.1-2
】
标识符的长度应当符合“
min-length
&&
max-
information
”
原则;
☆
【规则
2.1-3
】
命名规则尽
量与所采用的操作系统或开发工具的风格保持
一致;
☆
【规则
2.1-4
】
程序中不要出现仅靠大小写区分的相似的标识符。
☆
【规则
2.1-5
】
程序中不要
出现标识符完全相同的局部变量和全局变量,
尽
管两者的作用域
不同而不会发生语法错误,但会使人误解;
☆
【规则
2.1-6
】
变量的名字应当使用“名词”或者“形容词+名词”;
☆
【规则
2.1-7
】
全局函数的
名字应当使用“动词”或者“动词+名词”
(
动
宾词组
)
;
☆
【规则
2.1-8
】
用正确的反
义词组命名具有互斥意义的变量或相反动作的
函数等;
☆
【建议
2.1-1
】
尽量避免名
字中出现数字编号,
如
Value1,Value2
等,
除非
逻辑上的确需要编号;
< br>
注:
2.1.1
标识符最好采用英文单词或其组合,便于记忆和阅读,切忌使用汉语
拼音来命名,程
序中的英文单词一般不要太复杂,用词应当准确,例如
不要把
C
urrentValue
写成
NowValue
;
2.1.2
标示符的长度应当以最小的长度实现最多信息,一般来说,长名字能
更好地表达含义,但并非长的变量名就一定要比短的变量名要好,此外
单字符的名字
也是有用的,常见的如
i,j,k,m,n,x,y,z
等,它
们通常可
用作函数内的局部变量;
2.1.3
不同的操作系统的程序设计风格是不一样的,例如
Windows
< br>应用程序
的标识符通常采用“大小写”混排的方式,如
A
ddChild
,而
Unix
应用
p>
程序的标识符通常采用“小写加下划线”的方式,如
add_chi
ld
,别把
这两类风格混在一起使用;
2.2 Windows
变量命名规则
☆
【规则
2.2-1
】
变量的命名
规则要求采用
“匈牙利法则”
,
即开头
字母用变
量的类型,其余部分用变量的英文意思或其英文意思的缩
写,尽量避免采用中文拼音,要求单词的第一个字母大写;
即:变量名=变量类型+变量英文意思
(
或缩写
)
变量类型请参见附表
1
-
变量类型表;
☆
p>
【规则
2.2-2
】
类名和函数名用大写字母开头的单词组合而成;
对
struct
、
union
、
class
变量的命名要求定义的类型用大写,结构采<
/p>
用
S
开头,联合体采用
< br>U
开头,类采用
C
开头;
例如:
struct SPoint
{
};
union
URecordLen
{
}
class CNode
{
};
☆
【规则
2.2-3
】
< br>
指针变量命名的基本原则为:
一重指针变量的基本原则为:
变量名=
“
p
”+变量类型前缀+命名
//
类成员变量或成员函数
BYTE
BYTE
m_byRecordNum;
m_byRecordLen;
int
m_nX;
int
m_nY;
对多重指针变量的基本原则为:
二重指针:
变量名=“
pp
”+变量类型前缀+命名
三重指针:
变量名=“
ppp
”+变量类型前缀+命名
< br>
......
例如一个
sh
ort*
型的变量应该表示为
pnStart
< br>;
☆
【规则
2.2-4
】
p>
全局变量用
g_
开头;例如一个全局的长型
变量定义为
g_lFileNum
,
即:
变量名=
g_
+变量类型+变量的英文意思
(
或缩写
)
;
☆
【规则
2.2-5
】
< br>
静态变量采用
s_
开头;例如
一个静态的指针变量定义为
s_plPrevInst
,
即:
变量名=
s_
+变量类型+变量的英文意思
(
或缩写
)
;
☆
【规则
< br>2.2-6
】
类成员变量采用
m_
开头;例如一个长型成员变量定义为
m_lCount
,
即:
变量名=
m_
+变量类型+变量的英文意思
p>
(
或缩写
)
;
p>
☆
【规则
2.2-7
】
对
const
的变量要求在变量的命名规则前加入<
/p>
c_(
若作为函
数的输入参数,可以不加
)
,
即:变
量名=
c_
+变量命名规则,例如:
const char*
c_szFileName
;
☆
【规则
2.2-8
】
对枚举类型
(enum)
中的变量,
要求用枚举变
量或其缩写做前
缀,
且用下划线隔离变量名,
< br>所有枚举类型都要用大写,
例
如:
enum
{
EMDAYS_MONDAY;
EMDAYS_TUESDAY;
......
EMDAYS
}
;
☆
【规则
2.2-9
】
对常量
p>
(
包括错误的编码
)
命名,
要求常量名用大写,
常量名
用
英文意思表示其意思,用下划线分割单词,例如:
#define
CM_7816_OK
0x9000
;
☆
【规则
2.2-10
】
为了防止
某一软件库中的一些标识符和其它软件库中的
冲突,
可以为各种
标识符加上能反映软件性质的前缀。
例如
三维图形标准
OpenGL
的所有库函数均以
gl
开头,
所有常量
(或宏定义)均以
GL
开头。
3
程序风格
程序风格虽然不会影响程序
的功能,但会影响程序的可读性,追求清晰、美
观,是程序风格的重要构成因素。
3.1
空行
<
/p>
空行起着分隔程序段落的作用。空行得体(不过多也不过少)将使程序的布
局更加清晰。
空行不会浪费内存,
虽然打印含有空行的
程序是会多消耗一些纸张,
但是值得。
☆
【规则
3.1-1
】
< br>
在每个类声明之后、
每个函数定义结束之后都要加空行
。
参
见示例
3.1(a)
;
☆
p>
【规则
3.1-2
】
在一个函数体内,
逻揖上密切相关的语句之间不加空行,<
/p>
其
它地方应加空行分隔。参见示例
3.1
(b)
;
// blank line
void
Function1(
…
)
while (condition)
{
{
…
}
// blank line
void
Function2(
…
)
{
…
}
// blank line
//
blank line
if
(condition)
{
}
else
statement2;
statement1;
//
blank line
void
Function3(
…
)
{
…
}
{
}
//
blank line
statement3;
statement4;
}
示例
3.1(a)
函数之间的空行
示例
3.1(b)
函数内部的
空行
3.2
代码行
☆
【规则
3.2-1
】
< br>
一行代码只做一件事情,
如只定义一个变量,
或只写一条语
句
,
这样
的代码容易阅读,并且方便于写注释;
☆
【规则
3.2-2
】
if
、
for
、
whil
e
、
do
等语句自占一行,执行语句不
得紧跟
其后,
不论执行语句有多少都要加
{}
,
这样可以防止书写失
误;
p>
☆
【规则
3.2-3
】
if
、
for
、
while
、
do
等语句
的“
{
”要单独占用一行;
☆
【建议
3.2-1
】
所有函数内的变量都在函数开始处定义;
☆
【建议
3.2-2
】
尽可能在定
义变量的同时初始化该变量
(
就近原则
)
,
如果变
量的引用处和其定义处相隔
比较远,
变量的初始化很容易被
忘记。
如果引用了未被初始化的变量,
可能会导致程序错误,
本建议可
以减少隐患。
< br>示例
3.2(a)
为风格良好的代码行,示例
3.2(b)
为风格不良的代码行。
int nWidth;
// width
int
nHeight;
// height
int nDepth;
//
depth
x = a + b;
y = c + d;
z = e
+ f;
if (nWidth < nHight)
{
}
for
(initialization; condition; update)
{
DoSomething();
}
//
blank line
Other();
DoSomething();
int nWidth,nHight,nDepth;//width,height
,depth
X
=
a + b; y =
c + d; z = e + f;
if (nWidth < nHight)
DoSomething();
for
(initialization; condition; update)
DoSomething();
Other();
示例
3.2(a)
风格良好
的代码行
示例
3.2(b)
风格不良
的代码行
3.3
代码行内的空格
☆
【规则
3.3-1
】
关键字之后
要留空格,
象
const
、
virtual
、
inline
< br>、
case
等
关键字之后至少
要留一个空格,否则无法辨析关键字,象
if
、
for
、
while
等关键字
之后应留一个空格再跟左括号
‘
(’
,
以突出关键字;
☆
【规则
3.3-2
】
函数名之后
不要留空格,紧跟左括号‘(’,以与关键字区
别;
☆
【规则
3.3-3
】
‘(’向后
紧跟,‘)’、‘,’、‘
;
’向前紧跟,紧跟
处不留空格;
☆
【规则
3.3-4
】
< br>
‘,’之后要留空格,如
Function(x,
y, z)
,如果‘
;
’
不是一行的结束符号,其后要留空格,如
for
(initialization; condition;
update)
;
☆
【规则
3.3-5
】
赋值操作符
、比较操作符、算术操作符、逻辑操作符、位域
操作符,如“
=
”、“
+=
”
“
>=
”、“
<=
”、“
+
”、“
< br>*
”、
“
%
”、“
&&
”、“
||
”、“
<<
”
,
“
^
”等二元操作符的前
后应当加空格;
☆
【规则
3.3-6
】
< br>
一元操作符如“
!
”、“
p>
~
”、“
++
”、
“
--
”、“
&
”(地
址运算符)等前后不加空格;
☆
【规则
3.3-7
】
象“[]”
、“
.
”、“
->
”这类操作符前后不加空格;
☆
【建议
3.3-1
】
< br>
对于表达式比较长的
for
语
句和
if
语句,为了紧凑起见可
以适当
地去掉一些空格,如
for (i=0; i<10;
i++)
和
if
((a<=b)
&& (c<=d))
void
Func1(int x, int y, int z); // favorable
style
void Func1 (int x,int y,int z);
// ill style
if (year >= 2000)
// favorable style
if(year>=2000)
// ill style
if ((a>=b) && (c<=d))
// favorable style
if(a>=b&&c<=d)
// ill style
for (i=0; i<10; i++)
// favorable style
for(i=0;i<10;i++)
// ill style
for (i = 0; I < 10; i ++)
// favorable style
x = a < b ? a : b;
// favorable style
x=a
int *x = &y;
// favorable style
int * x = & y;
// ill style
array[5] = 0;
// Do not use array [ 5 ] =
0;
on(); //
Do
not
use
a
.
Function();
b->Function();
// Do not use b ->
Function();
示例
3.3
代码行内的空格
3.4
对齐
☆
【规则
3.4-1
】
程序的分界
符‘
{
’和‘
}
’应独占一行并且位于同一列,同
时与引用它们的语句左对齐;
☆
【规则
3.4-2
】
{ }
之内的代码块在‘
{
’右边数格处左对
齐;
☆
【规则
3.4.3
】
p>
代码的的对齐采用
TAB
键而不采用空格键
对齐,一般
TAB
键设置为向后空
4<
/p>
个空格。
示例
3.4(a)
为风格良好的对齐,
示例
3.4(b)
为风格不良的对齐。
void
Function(int x)
{
…
// program code
}
if
(condition)
{
…
// program code
}
void
Function(int x){
…
// program code
}
if (condition){
…
// program code
}
else
{
-
-
-
-
-
-
-
-
-
上一篇:c语言元素周期表
下一篇:语法填空专项训练4篇(附答案及解析)