统一、合理、美观的代码格式能显著增强程序的可读性和可维护性,还可以帮助预防和发现错误(问题越早发现代价越小)。因此将培养良好编码风格的有关规范列于首要位置。
原则1:水平缩进每次1个制表符(tab)
说明
其他字间填充用空格。
例子
class Z_AbstractMutex_T
{
public :
Z_AbstractMutex_T (void); // defaault constructor
Virtual ~z_AbstractMutex_T(void); // for destruct derived obj.
virtual int lock (void)=0; // lock interface
virtual int unlock(void)=0; // unlock interface
virtual int trylock (void)=0; // trylocit interface
private : // DISALLOW USE ANYWHERE
Z_AbstractMutex_T (const Z_AbstractMutex_T&); // copy constructor
Z_AbstractMutex_T&operator= (const Z_AbstractMutex_T&); // operator=
};
原则2: 不要在引用操作符前后加空格
说明
引用操作符指“.”“->”和“[]”。
例子
foo.bar,pFoo->bar,foo[bar]
原则3: 不要在单目操作符和其操作对象间加空格
例子
!foo,~foo,++foo,-foo,+foo,*pFoo,&foo,sizeof (foo),(int)foo
原则4: 在“,”“;”之后(而不是之前)加空格
例子
for (i=0,j=0; i<10; i++,j++)
原则5: 文件中的主要部分用空行分开
原则6: 函数间要用空行分开
例子
void function1 (void)
{
//...
}
void function2 (void)
{
//…
}
原则7: 局部变量声明和代码之间用空行分开
例子
void myFunction (void)
{
int1;
char c;
for (i=0;i<LENGTH;i++)
//…
}
原则8: 用空行将代码按逻辑片断划分
原则9: 函数返回语句要和其他语句用空行分开
例子
MyClass_T&
MyC1ass_T::operator= (MyClass_T const&rhs)
{
if (this !=rhs)
{
//…
}
return (*this); // 返回语句之前加一空行
}
例外
除非该函数过于简单(比如只有一两条语句)。
原则10: 每一行不超过80个字符
说明
因为标准显示/输出设备(字符终端、缺省宽度的显式窗口、打印机等)的宽度都大于等于80个字符,所以每行不超过78个字符可以保证代码在显示、编辑、打印等情况下都不会发生因为宽度不够而折行的现象。
限制为78个是因为行尾还隐含一至二个回车换行符(OxOd或OxOdOa)。
原则11: 当一条语句超过78个字符时按逻辑划分成不同行
原则12: 花括号{ }要单独占一行
说明
并且和其控制语句的缩进相同。有个别例外:
在do-while循环中,“}”要和while在一行。
结构(struct)和联合Union)结尾紧跟变量定义,要和“}”放在一行。
任何“}”后紧跟分号要放在一行。
例子
// {}单独占一行,并且和if /for语句缩进相同
if (clearRequested)
{
for (i=0;I<LENGTH;i++)
{
//…
}
}
else
{
//…
}
// do-while例外
do
{
//…
} while (length-- > 0); // 放在一行
// 结构和联合的例外
typedef struct
{
//…
} Message; // 放在一行
// 花括号后紧跟分号的情况
class MyClass_T
{
//…
}; // 放在一行
原则13: 花括号中没有或只有一条语句时也不省略花括号
例子
// 这种方式表达空循环不够清楚
for (i=0;i<TIMEOUT;i++);
// 即便是空循环,也保留{},这样就清楚多了
for (i=0;i<TIME0UT;i++〉
{
}
原则14: 不要在一行中放多于一条语句
例子
// 两条语句放在一行
if (buffer.empty()) status=ERROR_EMPTY; //error
// 这样要清晰一些
if (buffer.empty())
{
status=ERROR_EMPTY;
}
原则15: 语句switch中的每个case各占一行
例子
switch (debugLevel)
{
// error
case DEBUG_LEVEL_VERBOSE: case DEBUG_LEVELINF0:
//…
break;
default:
//…
}
// 应该这样
switch (debugLeve1)
{
case DEBUG_LEVEL_VERBOSE:
case DEBUG_LEVEL_INFO:
//…
break;
default:
//…
}
原则16: 为所有switch语句提供default分支
原则17: 若某个case不需要break,一定要加注释声明
说明
但case中没有执行语句的情况除外。
例子
switch (ch)
{
case 'a' :
case'A' :
action=Action_T::ABORT;
break;
case 'v' :
case 'v' :
verbosity++;
// Fall through
case 'd' :
//…
break;
default:
//…
}
原则18: 变量定义应集中放置、各占一行。
说明
C++允许变量定义出现在一个代码块(block)的任意位置,但为了方便阅读和维护,建议还是集中放在代码块的开头。
例子
// 不好理解每个变量的类型
int*pCount,flexPages,reflexPages;
// 这样就清楚多了
int flexPages;
int* pCount;
int ref1exPages;
原则19: 定义指针和引用时*和&紧跟类型
例子
int* pCount;
int& count;
原则20: 按编译器解析顺序旋转变量声明的修饰符
例子
// 两句话意思完全一样,但后者更清楚
const char* pName;
char const *pName;
原则21: 关于函数声明和定义的格式
说明
函数声明原则上放在一行。但函数定义(实现)应按下列顺序放在多行中:
1)模板描述;
2)修饰符和返回值类型;
3)函数名及其参数,若需要,参数可放在多行中;
4)函数体。
例子
// 函数声明
int function (void);
// 函数定义(实现)
template<class KEY_T,class VALUE_T >
void
HA_CheckPointTable_T〈KEY_T,VALUE_T>::myFurlction(
const char*pStoreFileName,
size_t tablesize,
size_t syncInterval,
float perfomanceCoeff
)
{
//…
}
原则22: 函数名和左括号间不要空格
例子
int function(int argument);
原则23: 关于字符常量
例子
char c= 'x'; // 尽量不要用0x78、0170或120
if (c=='\b') // 用定义好的标识符号,而不是直接用值
原则24: 关于换行
例子
someMethod(longException1, longException2, longException3,
longException4, longException5)
omeMethod1(longException1, someMethod2(longException2,
longException3))
原则25: 左括号和后一个字符之间不应该出现空格, 同样, 右括号和前一个字符之间也不应该出现空格。
例子
CallProc( AParameter ); // 错误
CallProc(AParameter); // 正确
原则26:不要在语句中使用无意义的括号. 括号只应该为达到某种目的而出现在源代码中。
例子
if ((I) = 42) { // 错误 - 括号毫无意义
if (I == 42) or (J == 42) then // 正确 - 的确需要括号
原则27: 初始化。尽量在申明局部变量的同时初始化。
例子
int count = 0;
原则28: 所有的二元运算符,除了“.”,应该使用空格将之与操作数分开
例子
a += c + d;
a = (a + b) / (c * d);
while (d++ = s++)
{
n++;
}
原则29: for语句中的表达式应该被空格分开
例子
for (expr1; expr2; expr3);
原则30: 强制转型后应该跟一个空格
例子
myMethod((int) aNum, (int*) x);
原则31: final 类。绝对不要因为性能的原因将类定义为 final 的(除非程序的框架要求)如果一个类还没有准备好被继承,最好在类文档中注明,而不要将她定义为 final 的。这是因为没有人可以保证会不会由于什么原因需要继承它。
- 第一章 概述
- 1.1规范制定原则
- 1.2 术语定义
- 1.3 文件命名组织
- 1.3.1文件命名
- 1.3.2文件注释
- 第二章 编码风格
- 第三章 注释
- 3.1 注释概述
- 3.2 文档型注释
- 3.3 类c注释
- 3.4 单行注释
- 3.5 注释标签
- 第四章 声明
- 4.1每行声明数
- 4.2初始化
- 4.3位置
- 4.4类和接口的声明
- 4.5字段的声明
- 第五章 命名规范
- 5.1命名概述
- 5.2大小写规则
- 5.3缩写
- 5.4命名空间
- 5.5类
- 5.6接口
- 5.7属性 (Attribute)
- 5.8枚举 (Enum)
- 5.9参数
- 5.10方法
- 5.11属性 (property)
- 5.12事件
- 5.13 常量 (const)
- 5.14 字段
- 5.15 静态字段
- 5.16 集合
- 5.17 措词
- 第六章 语句
- 6.1每行一个语句
- 6.2 复合语句
- 6.3 return 语句
- 6.4 if、 if-else、if else-if 语句
- 6.5 for、foreach 语句
- 6.6 while 语句
- 6.7 do - while 语句
- 6.8 switch - case 语句
- 6.9 try - catch 语句
- 6.10 using 块语句
- 6.11 goto 语句
- 第七章 函数与类
- 第八章 内存分配和释放
- 第九章 兼容性
- 第十章 控件命名规则
- 10.1 命名方法
- 10.2 主要控件名简写对照表
- 附录一: 匈牙利命名法