翻译】geosoft C++ Programming Style Guidelines (已翻译完毕,大家看看自己总结出了哪些吧!)
REF : http://geosoft.no/development/cppstyle.html
个人意译-大家可以随时拍砖讨论心得!^)
24、29 、53、 57 求助 `~`
1 介绍
这份文档罗列了C++ 开发社区中基本相同的编程指导。
指导是基于大量的代码、个人经验、实际需求及其他资料中的建议 [1] - [4]
使用一份新的指导而不是引用这些资料中主要的原因就是这些这些指导过于宽泛,我们需要更加具体的规则(尤其是命名方面)。同样,整个指导把规则增加了注释,使得在代码审计中要比之前的规则指导易于使用。值得一提的是,编程指导中包含着许许多多方面,这份文档集中在代码规则上,其他可以参考 C++ Programming Practice Guidelines.
IDE提供了代码隐藏、上色和自动格式化等等功能,但程序员不应该依靠这些特性。源代码不应当局限在当前正在使用的IDE中,而是在写代码时要使他尽量能够在任何类型的IDE下都可以清晰的阅读
1.1 指南的样式
指南以话题的形式组合,并且每个指南都有一个可以用于引用的标号
n. 指南简单描述 |
可能的例子 |
原因、背景、附加信息 |
第三段很重要,代码编写标准通常会引起“圣战” 标注出每种标注的使用背景就很重要了:)
1.2 指南的重要性
在指南里,分为必须、应该和推荐三种等级。
2 通用指南
1. 任何违反本指南但提高代码阅读性的方法都是允许的 |
指南的主要目的就是增加代码的可读性,提供代码质量。让代码更好的被理解和维护。在这种指南中对于特殊情况的事件是无法包括的,需要程序员灵活的运用。 |
2.如果个人不喜欢这种方式,可以违背指南 |
制作这份文档的目的是为了指南,而不是规定一种必需人人遵守的规则。有经验的程序员通常有自己的一种类似于本指南的方法。但有这样一份指南,当需要人来所熟悉、理解它,通常可以使人们考虑编程的方法,评估他们自己在这一领域的习惯。 另一方面来说,对于新程序员和尚缺少经验的程序员们想要更快的进入编程这个行业中,遵循一份代码指南是一条方便、简单的道路 |
3 命名惯例
3.1 常见的命名惯例
3. 命名变量类型时必须用起始字母大写的单词 |
Line, SavingsAccount |
Common practice in the C++ development community. |
4. 变量必须的起始字母小写 |
line, savingsAccount |
Common practice in the C++ development community. 使得变量与类型可以清晰的分辨,也解决了变量与类型名的冲突 Line line |
5. 命名常量应当使用全大写字母,单词之间使用下划线连接 |
MAX_ITERATIONS, COLOR_RED, PI |
Common practice in the C++ development community. 通常情况下,常量的使用应该控制在最小限度内,在很多情况下可以把值变为方法:
int getMaxIterations() // NOT: MAX_ITERATIONS = 25 { return 25; } 这样既清晰阅读,又确保了这个接口对于类来说值是统一的。 |
6. 命名函数时一定要使用动词并且起始字母小写。 |
getName(), computeTotalWidth() |
C++社区常用规范。 与命名变量类似,但是C++中的函数可以被它自己的特有的方式识别出来。 |
7. 命名空间应该使用小写 |
model::analyzer, io::iomanager, common::math::geometry |
C++社区常用规范。 |
8. 命名模板类型应该使用一个单一的大写字母。 |
template<class T> ... template<class C, class D> ... |
C++社区常用规范。 这样使得模板名称与其他使用的名称清晰的独立出来 |
9. 简略词必须不使用全大写 |
exportHtmlSource(); // NOT: exportHTMLSource(); openDvdPlayer(); // NOT: openDVDPlayer(); |
使用全大写的缩略词会导致冲突,像dVD,hTML这类的同样也不利于阅读,而且当略缩词后面连接了一个单词后,会减少后面单词的可读性。 |
10. 全局变量应当使用操作符:: |
::mainWindow.open(), ::applicationContext.getName() |
通常应该避免使用全局变量,考虑单间模式的对象来代替。 |
11. 私有类变量应该使用下划线字尾. |
class SomeClass { private: int length_; } |
除了变量的名称和类型,作用域是一个变量最重要的属性。 its name and its type, the scopeof a variable is its most important feature. 通过下划线来区分局部变量和类的私有变量是很方便的事情。因为类变量具有比函数变量更大的作用域因此应当值得程序员的注意。
同时还使得当变量出现问题时,更方便的解决。 void setDepth (int depth) 值得注意的是变量作用域标识的问题已经有很长时间了,这个指南中这条规则被更多的应用了。 |
12. 通用的变量名应该与类型名一致 |
void setTopic(Topic* topic) // NOT: void setTopic(Topic* value) // NOT: void setTopic(Topic* aTopic) // NOT: void setTopic(Topic* t) void connect(Database* database) // NOT: void connect(Database* db) // NOT: void connect (Database* oracleDB) |
通过减少不同变量名等方法来减少代码的复杂度,同样使得通过变量名猜测变量类型变得容易。 如果某些情况下无法满足这条指南,非通用的变量会有一个特殊的角色,那么这些变量可以把角色和类型联合起来: Point startingPoint, centerPoint; |
13. 所有名称应该使用英语 |
fileName; // NOT: filNavn |
在国际化开发中,英语是首推语言。 |
14. 变量的作用域长,使用长变量名,变量作用域短,使用短变量名。 |
用于短暂存储或序号等的临时变量应该尽量保持简单。一个程序员在读到这些变量就可以推断出变量的值不会在外部使用,而且只是作用于很少行代码。常见的临时变量有:整数:i、j、k、m、n 字符: c、d |
15. 对象名是一种暗示,应该避免再次出现在方法中 |
line.getLength(); // NOT: line.getLineLength(); |
在类定义时函数看起来似乎正常,但在上例中可以看的很清楚,多余了。 |
3.2 特定的命名指南
17. 当一个属性被允许修改,那么必须要通过使用get/set函数 |
employee.getName(); employee.setName(name); matrix.getElement(2, 4); matrix.setElement(2, 4, value); |
C++社区常用规范。在java中,这已经基本变成了一种标准。 |
18. 可以使用compute命名需要在函数内进行计算的函数 |
valueSet->computeAverage(); matrix->computeInverse() |
给阅读代码者一个清晰的认识,这里是一个潜在的消耗时间的操作,当需要重复时,就可以考虑缓存函数执行结果。一致的使用这种命名方式可以提高代码的可读性。 |
19. 可以使用find命名需要在函数内进行查找的函数 |
vertex.findNearestVertex(); matrix.findMinElement(); |
给阅读代码者一个清晰的认识,这是一个仅仅为了查找的操作,这种函数使用最少的操作。一致的使用这种命名方式可以提供代码的可读性。 |
20. initialize 可以用来命名一个对象或强模板的建立。 |
printer.initializeFontSet(); |
美式的initialize要比英式的initialise好. 不应该使用略缩词init |
21. 代表着可视化组件的变量,应该具有组件类型的后缀名。 |
mainWindow, propertiesDialog, widthScale, loginText, leftScrollbar, mainForm, fileMenu, minLabel, exitButton, yesToggle etc. |
增加可读性,可以直观的看出变量类型和对象资源。 |
22. 当表示多个对象时,应该使用复数形式。 |
vector<Point> points; int values[]; |
增加可读性,可以直观的看出变量类型和可以应用于此种类型的操作。 |
23. 当表示多个对象的个数时,应该使用前缀n |
nPoints, nLines |
在数学界中表示对象数目的方式。 |
24.当表示一个实体的序号时,应该使用后缀 |
tableNo, employeeNo |
在数学界中表示实体的方式。 一种优雅的替换方式是使用前缀i:iTable, iEmployee。在迭代器中使用。( This effectively makes them named iterators. ) |
25. 迭代器中的变量应该起名为i、j、k等 |
for (int i = 0; i < nTables); i++) { : } for (vector<MyClass>::iterator i = list.begin(); i != list.end(); i++) { Element element = *i; ... } |
在数学界中表示迭代变量的方式。
变量名为j、k等变量,应该只在紧凑的循环中使用。 |
26. 前缀is应该在布尔变量或返回布尔值的函数中使用。 |
isSet, isVisible, isFinished, isFound, isOpen |
C++社区通用规范 及 java部分强制需求。
使用is前缀解决了一个常见的布尔变量命名问题,使用stauts、flag通常是比较差的布尔变量名。 有一些替换的变量前缀可能更加使用:has、can和should: bool hasLicense(); bool canEvaluate(); bool shouldSort(); |
27. 互补的名字必须用于互补的操作 |
get/set, add/remove, create/destroy, start/stop, insert/delete, increment/decrement,old/new, begin/end, first/last, up/down, min/max, next/previous, old/new, open/close, show/hide, suspend/resume |
通过对称减少复杂性 |
28. 应该避免缩写 |
computeAverage(); // NOT: compAvg(); |
有两类单词,一类是经常会被使用的单词,永远不要缩写他们:
cmd instead of command 还有一类是具有特殊含义的短语,基本被所有人所熟知,要使用这种缩写: HypertextMarkupLanguage instead of html |
29. 对于指针的特殊命名应该避免 |
Line* line; // NOT: Line* pLine; // NOT: LIne* linePtr; |
在C/C++ 环境中,许多变量都是指针,因此许多约定都无法遵守。同样在C++中对象经常不具有明显的类型,程序员应该避免特殊的实习。只有当一个对象的实际类型特别重要时,变量名才应该着重它的类型。(Many variables in a C/C++ environment are pointers, so a convention like this is almost impossible to follow. Also objects in C++ are often oblique types where the specific implementation should be ignored by the programmer. Only when the actual type of an object is of special significance, the name should emphasize the type. ) |
30. 必须避免否定的布尔变量名 |
bool isError; // NOT: isNoError bool isFound; // NOT: isNotFound |
这样做的问题是在逻辑判断中使用了双重否定无法第一时间判断出含义: !isNotFound |
31. 枚举常量应具有一个共同的前缀类型名 |
enum Color { COLOR_RED, COLOR_GREEN, COLOR_BLUE }; |
这样命名增加了额外信息,哪里可以找到这些变量、哪几种常量是一起的以及代表了什么样的内容。
一种替代方式是保持通过类型进行引用Color::RED, Airline::AIR_FRANCE 注意枚举类型的变量名应该是单数形式enum Color {...}.一个复数的名字尽管看起来没有什么区别,但在使用时看起来非常愚蠢。 |
32. 异常函数应当具有后缀Exception. |
class AccessException { : } |
异常函数不应该作为程序的主要设计部分,如此命名使得它远离其他的函数。 |
33. 函数(方法具有返回值)应当被命名为他们返回的事物,过程(方法返回为空)应该被命名为做了何事。 |
增加可读性,使得可以清晰的看到这个单元应该怎么用特别是什么不支持。这同样使得它避免了边界效应的影响。 |
4 文件
4.1 源文件
1
34. C++的头文件应该具有.h(推荐)或.hpp的扩展名 源文件应该具有.c++、.C、.cc或.cpp的扩展名 |
MyClass.c++, MyClass.h |
符合C++文件扩展标准 |
35. 一个类应该声明在头文件中,定义在与类名相同的源文件中。 |
MyClass.h, MyClass.c++ |
容易找到某个给定的类,例外是模板类必须在.h文件中声明和定义。 |
36. 所有的定义都应该在源文件中。 |
class MyClass { public: int getValue () {return value_;} // NO! ... private: int value_; } |
头文件中应该声明一个接口,源文件中实现这个接口。当查找一个具体的实现代码时,那么我们就知道可以在源文件中找到。 |
37. 文件的内容必须保持在80列以内 |
80列是编辑器、终端、打印机、调试器中常见的宽度,文件在几个人之间传看应该保证这些约束。在代码传递时避免了被动断行,可以提高代码的可读性。 |
38. 像TAB 和 分页符一类的特殊字符必须避免使用 |
在多环境、多人编程时,这类字符一定会导致编辑器、打印机、终端或调试器的问题。 |
39. 必须让分行的代码显示明显 |
totalSum = a + b + c + d + e; function (param1, param2, param3); setText ("Long line split" "into two parts."); for (int tableNo = 0; tableNo < nTables; tableNo += tableStep) { ... } |
当一段代码超过80列需要进行分行,很难给出严格的规定何时进行分行,以上例子可以作为参考
通常:
|
4.2 Include
40. 头文件必须要包含一个头文件守护 |
#ifndef COM_COMPANY_MODULE_CLASSNAME_H #define COM_COMPANY_MODULE_CLASSNAME_H : #endif // COM_COMPANY_MODULE_CLASSNAME_H |
这样的语法结构用来避免编译错误。这样命名统一了头文件出现在源文件中的位置,避免了名字冲突。 |
41. Include语句应当按组排列,按照在系统中的位置进行排序,低等级的在最前方声明,每个组之间保留一个空行。 |
#include <fstream> #include <iomanip>
#include <qt/qbutton.h> #include <qt/qtextfield.h>
#include "com/company/ui/PropertiesDialog.h" #include "com/company/ui/MainWindow.h" |
除了可以给读者一个清晰的包含文件的结构,还可以直观的看出使用了哪些模块。
包含文件的路径永远不要使用绝对路径,编译器的指令才应用来指定包含文件的根目录。 |
42. Include语句必须只在文件的顶部 |
通用规范。避免了边界影响。当include声明在源代码中的某处时,可能会忽略它所带来的影响。 |
5 语句
5.1 类型
43. 在文件内部使用的变量应该在文件里面进行声明。 |
确保了信息隐藏 |
44. 类一定要按照public、protected和private的顺序来声明。每种类型必须要精确的组织出来,不应当有混合情况。(All sections must be identified explicitly. Not applicable sections should be left out. ) |
顺序就是最常用的放到第一位,这样当需要使用这个类时,可以在读到代码段protected或private时停止。 |
45. 类型转换必须要表示出来,不要依靠隐藏的类型转换 |
floatValue = static_cast<float>(intValue); // NOT: floatValue = intValue; |
这样程序员表面了他意识到了不同类型的转换,而需要进行。 |
5.2 变量
46. 变量应当在声明时被初始化。 |
这样确保了变量随时都是可用的。但当声明时无法确定初始值: int x, y, z; |
47. 变量不应当具有双重意义。 |
确保所有的概念都通过唯一的变量代表,不仅提供了可读性,还可用减少副作用带来的错误。 |
48. 全局变量的应用应该保持在最小化的范围。 |
在C++中没有使用全局变量、全局函数或作用整个文件内变量的理由。 |
49. 类变量不应当被声明为public |
public变量会破坏C++的信息隐藏和抽象。使用私有变量和访问函数来代替。有一种例外情况是当类像C中的结构体一样时,只包含数据。 值得注意结构体在C++中只是为了与C语言的兼容性,因此应当尽量不使用struct而是用类。 |
51. C++ pointers and references should have their reference symbol next to the type rather than to the name. |
float* x; // NOT: float *x; int& y; // NOT: int &y; |
The pointer-ness or reference-ness of a variable is a property of the type rather than the name. C-programmers often use the alternative approach, while in C++ it has become more common to follow this recommendation. |
53. 除了布尔变量及指针外,不应该隐式的比较0 |
if (nLines != 0) // NOT: if (nLines) if (value != 0.0) // NOT: if (value) |
翻译不通、It is not necessarily defined by the C++ standard that ints and floats 0 are implemented as binary 0. Also, by using an explicit test the statement gives an immediate clue of the type being tested.
It is common also to suggest that pointers shouldn't test implicitly for 0 either, i.e. if (line == 0) instead of if (line). The latter is regarded so common in C/C++ however that it can be used. |
54. 变量应当在最小的域内声明。 |
在一个范围内保持变量的操作,这样做可以控制变量的影响和副作用。 |
5.3 循环
55. 在for语句中只包括控制语句。 |
sum = 0; // NOT: for (i = 0, sum = 0; i < 100; i++) for (i = 0; i < 100; i++) sum += value[i]; sum += value[i];
|
增加维护性和可读性。一个清晰的控制信息和循环中包含的条件。 |
56.循环变量应该在循环开始前初始化。 |
isDone = false; // NOT: bool isDone = false; while (!isDone) { // : : // while (!isDone) { } // : // } |
57. 应当避免使用do-while循环 |
do-while循环的控制条件在底部,可读性差。读者需要浏览完整个循环才能看到循环的范围。
另外,do-while循环没有什么理由出现,任何do-while都可以简单的重写成while循环或for循环。减少这类使用提供可读性。(Reducing the number of constructs used enhance readbility. ) |
58. 应当避免在循环中使用break和continue语句。 |
只有他们比完成同样功能的结构化代码提供更清晰的可读性时才应当被使用。 |
60. 在无限循环中应当使用while(true) |
while (true) { : } for (;;) { // NO! : } while (1) { // NO! : } |
测试1既不是必要的也没有意义。for(;;)可读性不强,也不能清晰表明自己是一个无限循环。 |
5.4 条件语句
61. 复杂的条件判断必须避免,使用临时的布尔变量保存 |
bool isFinished = (elementNo < 0) || (elementNo > maxElement); bool isRepeatedEntry = elementNo == lastElement; if (isFinished || isRepeatedEntry) { : } // NOT: if ((elementNo < 0) || (elementNo > maxElement)|| elementNo == lastElement) { : } |
使用布尔变量,程序可以自解释,容易阅读、调试和维护。 |
62. 在if语句中,更常见的实例应当放在if中,例外放在else中。 |
bool isOk = readFile (fileName); if (isOk) { : } else { : } |
确保例外的事件没有在正常的路径上。对于可读性和代码性能都有影响。 |
63. 条件语句应该放在单独一行中。 |
if (isDone) // NOT: if (isDone) doCleanup(); doCleanup(); |
为了调试方便,写在同一行中,无法清楚的知道结果是真还是假。 |
64. 在判断中使用执行语句的返回值必须被避免 |
File* fileHandle = open(fileName, "w"); if (!fileHandle) { : } // NOT: if (!(fileHandle = open(fileName, "w"))) { : } |
可执行语句的作为条件难以阅读,尤其是C/C++的新手。 |
5.5 杂项
65. 应该避免魔数的使用,除了0、1,应当考虑声明常量来代替。 |
当一个数字无法表述自己的含义时,采用命名常量来提高代码的可读性。另一种做法是在使用这个数字时,写一个函数。 |
66. 浮点常数应当带有小数点和至少一位小数。 |
double total = 0.0; // NOT: double total = 0; double speed = 3.0e8; // NOT: double speed = 3e8; double sum; : sum = (a + b) * 10.0; |
强调了整数与浮点数的区别,同样,像最后的例子里,他表达了变量(sum)的类型,这仅仅从(a+b)中是无法看出来的。 |
67. 浮点常数应当在小数点前面包含一个数字。 |
double total = 0.5; // NOT: double total = .5; |
数字和表达方式借鉴于数学,所以应当尽量满足数学的语法。同样,0.5比.5具有更高的可读性,也不会使人看成是5 |
68. 函数一定要有返回值的类型。 |
int getValue() // NOT: getValue() { : } |
如果没有指示,那么C++会将int作为函数返回类型。程序员不应当依靠这种特性,它会使程序员迷惑于是否具有这种特性。( since this might be confusing for programmers not aware of this artifact. ) |
69. 不应当使用goto语句 |
Goto语句破坏了结构化的代码,只有在非常少的情况下(跳出一个深层的结构)才应该考虑使用,而且要保证类似的实习会导致阅读性下降。 |
70. 使用“0”而不是"NULL" |
NULL 是C标准库中的,在C++中变为了绝对的0. |
6 代码结构与注释
6.1 结构
71. 最小间隔应该为2 |
for (i = 0; i < nElements; i++) a[i] = 0; |
间隔为1很难表述出代码的逻辑性,超过4的间隔又使得代码难以阅读并且大大增加了分行的可能能。2和4比3更通用一些。加上减少分行的可能行,我们选择了2作为间隔。 |
72. 代码块应该像1(推荐)、2 的结构一样,但绝对不要使用3中的样式。函数和类必须使用2 的结构。 |
||
while (!done) { doSomething(); done = moreToDo(); } |
while (!done) { doSomething(); done = moreToDo(); } |
while (!done) { doSomething(); done = moreToDo(); } |
比较起1和2,3在不需要额外的缩进等级也进行了缩进,使得代码结构不清晰。 |
73. 类的定义应当具有如下格式: |
class SomeClass : public BaseClass { public: ...
protected: ...
private: ... } |
这是上面一些规则的组合 |
74. 方法的定义应当按照如下方式: |
void someMethod() { ... } |
这是上面一些规则的组合 |
75. if-else结构应当按照如下方式: |
if (condition) { statements; }
if (condition) { statements; } else { statements; }
if (condition) { statements; } else if (condition) { statements; } else { statements; } |
这是上面一些规则的组合,有一些争议是关于else是否要与if语句的尾括号在同一行
if (condition) { statements; } else { statements; }我们选择了另起一行,这样在遇到例如需要移动else语句块时的情况可以方便一些。 |
76. 一个for语句应当使用如下格式: |
for (initialization; condition; update) { statements; } |
这是上面一些规则的组合 |
77. 一个空循环应当使用如下格式: |
for (initialization; condition; update) ; |
这强调了for的语句为空,让读者可以清晰的知道而不是忽略掉这个事实。不过,空循环应当被避免。 |
78. 一个while语句应当使用如下格式: |
while (condition) { statements; } |
这是上面一些规则的组合 |
79. 一个do-while循环应当使用如下格式: |
do { statements; } while (condition); |
这是上面一些规则的组合 |
80. 一个switch语句应当使用如下格式: |
switch (condition) { case ABC : statements; // Fallthrough
case DEF : statements;
case XYZ : statements; break;
default : statements; break; } |
注意每个关键词case在switch语句中都进行了对齐,这使得整个语句很清晰。同样要注意到在字符:处需要隔开。只要当一个case语句没有break时,都应当加上fallthrought的注释,来清晰的表明这里不需要break。 |
81. 一个try-catch语句应当按照如下格式: |
try { statements; } catch (Exception& exception) { statements; } |
这是上面一些规则的组合,而且关于if-else的讨论在这里同样适用。 |
82. 只有一句的if-else、for或while语句可以不使用括号。 |
if (condition) statement; while (condition) statement; for (initialization; condition; update) statement; |
通常的说,括号在这些语句中都应该使用的。但括号是用来组织一段代码的,在单一行的代码中使用显得多余,不过有一种反对的观点认为当增加语句时,会忘记增加括号。但是不论怎样,代码不应该是为了可能出现的变化来写的。( In general however, code should never be written to for changes that might arise. ) |
83. 函数的返回值可以放在函数名的正上方。 |
void MyClass::myMethod(void) { : } |
在文件中,函数名在第一列更好认一些。 |
6.2 空格
84. - C++ 关键词后面使用1个空格的间隔。 - 逗号应当在后面有1个空格的间隔。 - 冒号前后都使用空格。 - 语句中的分号后面应该有1个空格。 |
a = (b + c) * d; // NOT: a=(b+c)*d while (true) // NOT: while(true) { ... doSomething(a, b, c, d); // NOT: doSomething(a,b,c,d);
case 100 : // NOT: case 100: for (i = 0; i < 10; i++) { // NOT: for(i=0;i<10;i++){ ... |
让语句中的每一部分独立出来,增加可读性,很难给出一份完整的清单,就通过例子给出了一些使用空格的方法吧。 |
85. 方法名的后面还有单词时可以跟1个空格 |
doSomething (currentFile); |
让每个名字都清晰的表现出来,增加可读性。没有后面的跟随单词,就可以忽略啦(doSomething()) 另一种变化的方法是在括号处进行分离:doSomething( currentFile );虽然这种方法确实也让每个名字都可以清晰的读出来,不过看上去不太自然,而且如果省掉一个空格,那么看起来非常不对称。 |
86. 在一个代码段中逻辑上区分的单元应该使用1个空行隔开。 |
Matrix4x4 matrix = new Matrix4x4();
double cosAngle = Math.cos(angle); double sinAngle = Math.sin(angle);
matrix.setElement(1, 1, cosAngle); matrix.setElement(1, 2, sinAngle); matrix.setElement(2, 1, -sinAngle); matrix.setElement(2, 2, cosAngle);
multiply(matrix); |
使用空行增加逻辑上的可读性。 |
87. 方法之间应该使用三个空行隔开。 |
使用更多的空间隔开方法,可以让类中方法清晰可见。 |
88. 声明变量时应该左对齐。 |
AsciiFile* file; int nPoints; float x, y; |
增加可读性,通过对齐可以清楚的看到变量的类型。 |
89. 当使用对齐可以增加可读性的时候,果断使用。 |
if (a == lowValue) compueSomething(); else if (a == mediumValue) computeSomethingElse(); else if (a == highValue) computeSomethingElseYet();
value = (potential * oilDensity) / constant1 + (depth * waterDensity) / constant2 + (zCoordinateValue * gasDensity) / constant3;
minPosition = computeDistance(min, x, y, z); averagePosition = computeDistance(average, x, y, z);
switch (value) { case PHASE_OIL : strcpy(phase, "Oil"); break; case PHASE_WATER : strcpy(phase, "Water"); break; case PHASE_GAS : strcpy(phase, "Gas"); break; } |
即使违反了指导,代码中有很多地方可以通过增加空格来提高代码的可读性。许多这种情况都是为了代码对齐。很难给出特定的指导,不过通过查看上面这段实现,相信可以得出通用的结论。 |
6.3 注释
90. 炫耀技巧的代码不需要注释——需要重写!! |
通过选用名字和清晰的结构,让代码尽量的可以自我解释,把注释控制在最小的使用范围中。 |
91. 所有的注释应该使用英文。 |
在国际化的编译环境中,英语是第一语言。 |
92. 包括多行注释在内,对于所有的注释都使用// |
// Comment spanning // more than one line. |
使用//确保多级注释可以准确的注释自己想要注释的内容。调试可以使用/* */
在//和注释内容之间应该有一个空格,而且注释应当以大写字母开头,以句号结束。 |
93. 注释应当与代码位置一致 |
while (true) { // NOT: while (true) { // Do something // Do something something(); something(); } } |
这样避免注释打乱了代码的逻辑结构。 |
94. 类和方法的初始注释应当按照javadoc的格式。 |
对于C/C++来说,JAVA的的文档要专业很多,得益于javadoc作为了开发核心的一个标准,它可以帮助把注释变为高质量的格式
这是C++中实现了类似功能的工具,使用了和javadoc一样的格式。 |
7 引用
[1] Code Complete, Steve McConnell - Microsoft Press
[2] Programming in C++, Rules and Recommendations, M Henricson, e. Nyquist, Ellemtel (Swedish telecom)
http://www.doc.ic.ac.uk/lab/cplus/c%2b%2b.rules/
[3] Wildfire C++ Programming Style, Keith Gabryelski, Wildfire Communications Inc.
http://www.wildfire.com/~ag/Engineering/Development/C++Style/
[4] C++ Coding Standard, Todd Hoff
http://www.possibility.com/Cpp/CppCodingStandard.html
[5] Doxygen documentation system
http://www.stack.nl/~dimitri/doxygen/index.html
致谢
Thanks to Robert P.J. Day for valuable contributions.
^~同样感谢下自己,哈哈哈