Google C++编程气势气魄指南(七):名目
副标题#e#
1.行宽原则上不高出80列,把22寸的显示屏都占完,怎么也说不外去;2.只管不利用非ASCII字符;3.UNIX/Linux下无条件利用空格,MSVC的话利用Tab也无可厚非;4.函数参数、逻辑条件、初始化列表:要么所有参数和函数名放在同一行,要么所有参数并排分行……
名目
代码气势气魄和名目确实较量随意,但一个项目中所有人遵循同一气势气魄长短常容易的,作为小我私家未必同意下述名目法则的每一处,但整个项目听从统一的编程气势气魄是很重要的,这样做才气让所有人在阅读和领略代码时越发容易。
1.行长度(Line Length)
每一行代码字符数不高出80。
我们也认识到这条法则是存有争议的,但如此多的代码都遵照这一法则,我们感受一致性更重要。
利益:倡导该原则的人认为强迫他们调解编辑器窗口巨细很野蛮。许多人同时并排开几个窗口,基础没有多余空间拓宽某个窗口,人们将窗口最大尺寸加以限定,一致利用80列宽,为什么要改变呢?
缺点:阻挡该原则的人则认为更宽的代码行更易阅读,80列的限制是上个世纪60年月的大型机的死板缺陷;现代设备具有更宽的显示屏,很轻松的可以显示更多代码。
结论:80个字符是最大值。破例:
1) 假如一行注释包括了高出80字符的呼吁或URL,出于复制粘贴的利便可以高出80字符;
2) 包括长路径的可以超出80列,只管制止;
3) 头文件掩护(防备反复包括第一篇)可以无视该原则。
2.非ASCII字符(Non-ASCII Characters)
只管不利用非ASCII字符,利用时必需利用UTF-8名目。
哪怕是英文,也不该将用户界面的文本硬编码到源代码中,因此非ASCII字符要罕用。非凡环境下可以适当包括此类字符,如,代码阐明外部数据文件时,可以适当硬编码数据文件中作为脱离符的非ASCII字符串;更常用的是(不需要当地化的)单位测试代码大概包括非ASCII字符串。此类环境下,应利用UTF-8名目,因为许多东西都可以领略和处理惩罚其编码,十六进制编码也可以,尤其是在加强可读性的环境下——如"\xEF\xBB\xBF"是Unicode的zero-width no-break space字符,以UTF-8名目包括在源文件中是不行见的。
3.空格照旧制表位(Spaces vs.Tabs)
只利用空格,每次缩进2个空格。
利用空格举办缩进,不要在代码中利用tabs,设定编辑器将tab转为空格。
#p#副标题#e#
4.函数声明与界说(Function Declarations and Definitions)
返回范例和函数名在同一行,符合的话,参数也放在同一行。
函数看上去像这样:
ReturnType ClassName::FunctionName(Type par_name1, Type par_name2) {
DoSomething();
...
}
假如同一行文本较多,容不下所有参数:
ReturnType ClassName::ReallyLongFunctionName(Type par_name1,
Type par_name2,
Type par_name3) {
DoSomething();
...
}
甚至连第一个参数都放不下:
ReturnType LongClassName::ReallyReallyReallyLongFunctionName(
Type par_name1, // 4 space indent
Type par_name2,
Type par_name3) {
DoSomething(); // 2 space indent
...
}
留意以下几点:
1) 返回值老是和函数名在同一行;
2) 左圆括号(open parenthesis)老是和函数名在同一行;
3) 函数名和左圆括号间没有空格;
4) 圆括号与参数间没有空格;
5) 左大括号(open curly brace)总在最后一个参数同一行的末端处;
6) 右大括号(close curly brace)老是单独位于函数最后一行;
7) 右圆括号(close parenthesis)和左大括号间老是有一个空格;
8) 函数声明和实现处的所有形参名称必需保持一致;
9) 所有形参应尽大概对齐;
10) 缺省缩进为2个空格;
11) 独立封装的参数保持4个空格的缩进。
假如函数为const的,要害字const应与最后一个参数位于同一行。
// Everything in this function signature fits on a single line
ReturnType FunctionName(Type par) const {
...
}
// This function signature requires multiple lines, but
// the const keyword is on the line with the last parameter.
ReturnType ReallyLongFunctionName(Type par1,
Type par2) const {
...
}
假如有些参数没有用到,在函数界说处将参数名注释起来:
// Always have named parameters in interfaces.
class Shape {
public:
virtual void Rotate(double radians) = 0;
}
// Always have named parameters in the declaration.
class Circle : public Shape {
public:
virtual void Rotate(double radians);
}
// Comment out unused named parameters in definitions.
void Circle::Rotate(double /*radians*/) {} // Bad - if someone wants to implement later, it's not clear what the
// variable means.
void Circle::Rotate(double) {}
#p#分页标题#e#
译者注:关于UNIX/Linux气势气魄为什么要把左大括号置于行尾(.cc文件的函数实现处,左大括号位于行首),我的领略是代码看上去较量简约,想想行首除了函数体被一对大括号封在一起之外,只有右大括号的代码看上去确实也舒服;Windows气势气魄将左大括号置于行首的利益是匹配环境一目了然。
5.函数挪用(Function Calls)
只管放在同一行,不然,将实参封装在圆括号中。
函数挪用遵循如下形式:
bool retval = DoSomething(argument1, argument2, argument3);
假如同一行放不下,可断为多行,后头每一行都和第一个实参对齐,左圆括号后和右圆括号前不要留空格:
bool retval = DoSomething(averyveryveryverylongargument1,
argument2, argument3);
假如函数参数较量多,可以出于可读性的思量每行只放一个参数:
bool retval = DoSomething(argument1,
argument2,
argument3,
argument4);
假如函数名太长,以至于高出行最大长度,可以将所有参数独立成行:
if (...) {
...
...
if (...) {
DoSomethingThatRequiresALongFunctionName(
very_long_argument1, // 4 space indent
argument2,
argument3,
argument4);
}
6.条件语句(Conditionals)
更倡导不在圆括号中添加空格,要害字else另起一行。
对根基条件语句有两种可以接管的名目,一种在圆括号和条件之间有空格,一种没有。
最常见的是没有空格的名目,那种都可以,照旧一致性为主。假如你是在修改一个文件,参考当前已有名目;假如是写新的代码,参考目次下或项目中其他文件的名目,还在彷徨的话,就不要加空格了。
if (condition) { // no spaces inside parentheses
...// 2 space indent.
} else { // The else goes on the same line as the closing brace.
...
}
假如你倾向于在圆括号内部加空格:
if ( condition ) { // spaces inside parentheses - rare
...// 2 space indent.
} else { // The else goes on the same line as the closing brace.
...
}
留意所有环境下if和左圆括号间有个空格,右圆括号和左大括号(假如利用的话)间也要有个空格:
if(condition) // Bad - space missing after IF.
if (condition){ // Bad - space missing before {.
if(condition){ // Doubly bad.if (condition) { // Good - proper space after IF and before {.
有些条件语句写在同一行以加强可读性,只有当语句简朴而且没有利用else子句时利用:
if (x == kFoo) return new Foo();
if (x == kBar) return new Bar();
假如语句有else分支是不答允的:
// Not allowed - IF statement on one line when there is an ELSE clause
if (x) DoThis();
else DoThat();
凡是,单行语句不需要利用大括号,假如你喜欢也无可厚非,也有人要求if必需利用大括号:
if (condition)
DoSomething(); // 2 space indent.
if (condition) {
DoSomething(); // 2 space indent.
}
但假如语句中哪一分支利用了大括号的话,其他部门也必需利用:
// Not allowed - curly on IF but not ELSE
if (condition) {
foo;
} else
bar;
// Not allowed - curly on ELSE but not IF
if (condition)
foo;
else {
bar;
} // Curly braces around both IF and ELSE required because
// one of the clauses used braces.
if (condition) {
foo;
} else {
bar;
}
7.轮回和开关选择语句(Loops and Switch Statements)
switch语句可以利用大括号分块;空轮回体应利用{}或continue。
switch语句中的case块可以利用大括号也可以不消,取决于你的爱好,利用时要依下文所述。
假如有不满意case列举条件的值,要老是包括一个default(假如有输入值没有case去处理惩罚,编译器将报警)。假如default永不会执行,可以简朴的利用assert:
switch (var) {
case 0: { // 2 space indent
...// 4 space indent
break;
}
case 1: {
...
break;
}
default: {
assert(false);
}
}
空轮回体应利用{}或continue,而不是一个简朴的分号:
while (condition) {
// Repeat test until it returns false.
}
for (int i = 0; i < kSomeNumber; ++i) {} // Good - empty body.
while (condition) continue; // Good - continue indicates no logic.while (condition); // Bad - looks like part of do/while loop.
8.指针和引用表达式(Pointers and Reference Expressions)
句点(.)或箭头(->)前后不要有空格,指针/地点操纵符(*、&)后不要有空格。
下面是指针和引用表达式的正确典型:
x = *p;
p = &x;
x = r.y;
x = r->y;
留意:
1) 在会见成员时,句点或箭头前后没有空格;
2) 指针操纵符*或&后没有空格。
在声明指针变量或参数时,星号与范例或变量名紧挨都可以:
#p#分页标题#e#
// These are fine, space preceding.
char *c;
const string &str;
// These are fine, space following.
char* c; // but remember to do "char* c, *d, *e, ...;"!
const string& str; char * c; // Bad - spaces on both sides of *
const string & str; // Bad - spaces on both sides of &
同一个文件(新建或现有)中起码要保持一致。
译者注:小我私家较量习惯与变量紧挨的方法。
9.布尔表达式(Boolean Expressions)
假如一个布尔表达式高出尺度行宽(80字符),如坚决行要统一一下。
下例中,逻辑与(&&)操纵符总位于行尾:
if (this_one_thing > this_other_thing &&
a_third_thing == a_fourth_thing &&
yet_another & last_one) {
...
}
两个逻辑与(&&)操纵符都位于行尾,可以思量特别插入圆括号,公道利用的话对加强可读性是很有辅佐的。
译者注:小我私家较量习惯逻辑运算符位于行首,逻辑干系一目了然,大师爱好罢了,至于加不加圆括号的问题,假如你对优先级了然于胸的话可以不加,但可读性老是差了些。
10.函数返回值(Return Values)
return表达式中不要利用圆括号。
函数返回时不要利用圆括号:
return x; // not return(x);
11.变量及数组初始化(Variable and Array Initialization)
选择=照旧()。
需要做二者之间做出选择,下面的形式都是正确的:
int x = 3;
int x(3);
string name("Some Name");
string name = "Some Name";
12.预处理惩罚指令(Preprocessor Directives)
预处理惩罚指令不要缩进,从行首开始。
纵然预处理惩罚指令位于缩进代码块中,指令也应从行首开始。
// Good - directives at beginning of line
if (lopsided_score) {
#if DISASTER_PENDING // Correct -- Starts at beginning of line
DropEverything();
#endif
BackToNormal();
} // Bad - indented directives
if (lopsided_score) {
#if DISASTER_PENDING // Wrong! The "#if" should be at beginning of line