Skip to content

代码风格指南

检测到 KaTeX 加载失败,可能会导致文中的数学公式无法正常渲染。

本文中所述的代码风格均建立在 Google C++ Style Guide 的基础之上,您可以在 GitHub 仓库 中找到与本文对应的 Clang Format 配置文件。

#整体结构

  1. 所有的 #include 语句均 必须 位于文件起始处;
  2. 如非必要,尽量不使用 using namespace 语句,防止污染命名空间;
  3. 如果函数实现部分过长,应先在文件头部声明函数,再在 main 函数后编写对应的实现;
  4. 每行长度不设硬性限制。

#预处理器指令

  1. 所有的预处理器指令 不能 缩进;
  2. 所有对标准库的引用,都应该使用 <> 而不是 ""
  3. 所有对 C 标准库的引用,都应该使用 <c_____> 代替 <_____.h>,如使用 <cstdio> 代替 <stdio.h>
  4. <iostream><cstdio> 的引用应位于所有引用语句之前,其余引用应按照文件名字典序排列。对本地头文件的引用应单独成块,并放置在对其他库的引用之后。
1
2
3
4
5
6
7
8
#include <algorithm>
#include <iostream>

#include "local.h"

#ifdef THROW_ERROR
#error "error"
#endif

#缩进

对于每个代码块,必须 使用 4 空格缩进。

1
2
3
int main(int argc, char *argv[]) {
return 0;
}

对于 class 中的访问修饰符(publicprivate 以及 protected),在原缩进基础上减少两个空格的缩进。

1
2
3
4
5
6
7
class SegmentTree {
private:
/* code */

public:
/* code */
};

#花括号

左花括号后 一般 不换行。

左花括号后、右花括号前 不留 空行。

1
2
3
if (/* condition */) {  // comment
/* code */
}

#命名

对于变量名使用下划线命名法,对于函数名和类名以下划线命名法为主,驼峰命名法为辅。

1
2
3
4
5
6
7
8
9
int max_value;

int query_max() { // recommend
return max_value;
}

int queryMax() { // also acceptable
return max_value;
}

#指针与引用

指针符号与引用符号贴靠右侧关键字,并在左侧留出一个空格。

1
node *root;

#条件语句

#if-else

if 语句中的代码块 尽量 使用花括号包裹。

如果一个 if 语句后还有后续的 else 语句,else 语句需要与前面的右花括号在同一行。

1
2
3
4
5
6
7
if (/* condition */) {
/* code */
} else if (/* condition */) {
/* code */
} else {
/* code */
}

短的 if 语句可以编写在同一行内,此时 不使用 花括号包裹代码。

1
2
3
if (/* condition */) /* code */
else if (/* condition */) /* code */
else /* code */

#switch

尽量 避免 使用 switch 语句。

switch 中的每个 case 中的语句 必须 使用花括号包裹起来,并与最后的 break 语句之间留出一个空行。

switch 中的每个 case 之间 必须 留有一个空行。

1
2
3
4
5
6
7
8
9
10
11
12
13
switch (/* expression */) {
case /* constant-expression */: {
/* code */

break;
}

default: {
/* code */

break;
}
}

#循环语句

#for

for 关键字和后面的左括号之间要有一个空格。

for 循环语句中的三个表达式要么同处一行之内,要么各自一行。

1
2
3
4
5
6
7
8
9
10
11
for (/* init-statement */; /* condition */; /* iteration-expression */) {
/* code */
}

// or

for (/* init-statement */;
/* condition */;
/* iteration-expression */) {
/* code */
}

#while

while 关键字和后面的左括号之间要有一个空格。

1
2
3
while (/* condition */) {
/* code */
}

#do-while

while 关键字和前面的右花括号、后面的左括号之间要有一个空格。

1
2
3
do {
/* code */
} while (/* condition */);

#函数

main 函数的返回值 必须int 类型的 0。

1
2
3
4
5
int main() {
/* code */

return 0;
}

声明函数时 一般情况下 只指定变量类型,不指定变量名。

1
void insert(int, const int&);

函数传参时 尽可能 使用 const 引用传参(const T&)。视情况使用引用传参和值传递。

1
2
3
4
5
void insert(int pos, const int& val) {
// 当代码中不会对 val 的值进行修改时,使用 const 引用传参形式

/* code */
}

多个函数之间 必须 用空行隔开。

#构造函数

构造函数的初始化列表应另起一行放置。

1
2
3
4
5
6
7
8
struct node {
int l, r;

node() {}

node(int _l, int _r)
: l(_l), r(_r) {}
};

#命名空间

命名空间内部的 必须 有 4 个空格的基础缩进,结尾处预留命名空间结尾注释。

1
2
3
namespace example {
/* code */
} // namespace example

#其他

  1. 非调试时 不能 使用 #define int long long
  2. 数组下标 尽可能 从 1 开始;
  3. 使用逗号隔开的语句,逗号前 不能 有空格,逗号后 必须 有一个空格;
  4. 不能 出现连续空行。