Studying Father's Code Style for OI

StudyingFather

2019-06-29 10:23:20

Personal

下面是 Studying Father 的 OI 代码规范,其来源主要为 Studying Father 的长期实践, [\_rqy的代码规范](https://rqy.moe/uncategorized/rqy-s-Code-Style-for-OI/), [Menci的代码规范](https://oi.men.ci/code-style-oi/)。 以后的代码应严格按照该规范实行~~(以前的就懒得管了...)~~。 ## Part 0 本文可能用到的词语解释 * **必须**:任何时候均要遵循的规范。 * **应该**:绝大多数正常情况下要遵循的规范,只允许在少数特殊情形下出现例外。 * **只能**:不能采用其他规范。 * **推荐**:这一规范符合通行规则,正常范围下优先使用。 * **可以/允许**:非强制性的规范,可以视情况实施。 * **不应/不推荐**:因为不符合通行规则,而在大多数情况下不使用该规则。 * **禁止**:任何时候均不能使用的规则。 ## Part 1 预编译语句 `#include`语句**必须**置于程序开头。 多个库的顺序**应该**遵循如下规则:首先是C库,接下来是C++库,最后是自定义库。 其中C库和C++库**禁止**使用`#include "foo"`,而**必须**使用`#include <foo>`。 C库**必须**使用以c开头,不带.h的头文件,旧有的以.h结尾,不带c的头文件不再使用。 **禁止**使用万能头文件。 `#define`**只能**用于定义常量标识符。且为了防止可能出现的问题,**不应**将值定义为复杂的常量表达式,而只是一个确定的数字。 例: ```cpp #define MAXN 1000+5 //wrong #define MAXN 1005 //correct ``` 再次强调,**禁止**使用`#define`来代替函数定义,以及缩写控制性语句。 **推荐**使用`const`定义常数,且这时无需考虑常量表达式的问题。 预编译指令**不应**缩进。(**应该**使用注释来标识各预编译指令的层次) ## Part 2 命名空间 **不推荐**使用`using namespace foo;`语句,而更**推荐**`using foo::fun;`。 注:该规范在工程中为应实施的规范,算法竞赛中并不强制。(主要是为了兼顾速度需求) 多子任务问题以及较复杂的数据结构**应该**使用命名空间来使得程序结构更工整,并减少可能的标识符冲突问题。 ## Part 3 代码风格 **应该**使用4空格缩进,不应使用Tab缩进(即使Tab的长度设置为4空格)。 目前阶段**允许**继续沿用1空格缩进。 大括号**应该**换行。且大括号位置应该与上一级代码块缩进相同。 **允许**遵循大括号最少原则,即在以下情况下**可以**省略大括号: 1. `if`语句后只跟随一条语句。这时**可以**把`if`语句和要执行的语句写在同一行,但**推荐**分开写。 2. `for`或`while`语句内只执行一条语句,这时**必须**将要执行的语句另起一行,且遵循缩进原则。 在嵌套`if`语句的情况下,为了避免歧义,**应该**加上必要的括号表示包含关系。 小括号用于标识运算执行顺序,在运算顺序不明的时候(比如出现位运算和逻辑运算符的时候)**应该**添加。 一行**不应该**超过80字符。较长的语句**应该**分写为若干行。 **允许**将几个联系紧密的较短语句用逗号连接。 ## Part 4 标识符命名 为方便调试需要,**应该**采用有意义的单词及其缩写作为标识符命名。 以下是一些常见标识符及其含义: * f/g/h:用于动态规划状态存储。 * v/val:变量的值。 * siz:变量所属空间的大小。 * cnt/tot:计数。 * dis/dist:距离。 * ans/res:ans常用于最终要输出的结果,res常用于中间结果。 诸如i/j/k等变量名通常只**允许**用于循环等场合,x/y/z等变量名只用于中间结果运算,较短数学运算函数形式参数等场合。 题目中给出的变量名**推荐**直接使用,减少后期调试压力。 ## Part 5 函数 `main()`的返回值**必须**是`int`,且结尾**不应**省略`return 0;`。 `inline`标识符选择性添加,平时应尽量少用。 为减少全局变量数量,**推荐**尽量传引用参数。 函数**应该**用于封装常用数学函数,数据结构常见操作,常用算法等,对于输入输出等简单内容**不推荐**再使用函数封装。 例如下面做法是**不推荐**的: ```cpp int main() { input(); solve(); output(); return 0; } ``` ## Part 6 结构体与类 算法竞赛中**不推荐**使用类`class`,而**推荐**使用结构体`struct`。 重载运算符在结构体内实现和在结构体外实现都**可以**接受。 **应该**使用构造函数初始化结构体与类。 需注意的是,列表初始化为 C++11 标准内容,应根据环境谨慎使用。 例: ```cpp struct node { int a,b; node(int x=0,y=0) { x=a,y=b; } } queue<node> q; node var1(4,5);//推荐写法 q.push({4,5});//注意列表初始化语法为 C++11 标准内容 ``` ## Part 7 杂项 任何时候均**禁止**使用`goto`语句。 任何时候均**禁止**使用`register`修饰变量。(`register`已经在C++17标准内弃用) 算法竞赛中`main`函数**应该**置于程序最后。 能用`bool`的场合**不推荐**使用`int`代替。 ## Part 8 例子 去看[猪国杀](https://studyingfather.com/archives/756)吧。