Studying Father's luogu blog

Studying Father's luogu blog

从零至灵,由壹达意

Studying Father's Code Style for OI

posted on 2019-06-29 10:23:20 | under 工具 |

下面是 Studying Father 的 OI 代码规范,其来源主要为 Studying Father 的长期实践, _rqy的代码规范Menci的代码规范

以后的代码应严格按照该规范实行(以前的就懒得管了...)

Part 0 本文可能用到的词语解释

  • 必须:任何时候均要遵循的规范。
  • 应该:绝大多数正常情况下要遵循的规范,只允许在少数特殊情形下出现例外。
  • 只能:不能采用其他规范。
  • 推荐:这一规范符合通行规则,正常范围下优先使用。
  • 可以/允许:非强制性的规范,可以视情况实施。
  • 不应/不推荐:因为不符合通行规则,而在大多数情况下不使用该规则。
  • 禁止:任何时候均不能使用的规则。

Part 1 预编译语句

#include语句必须置于程序开头。

多个库的顺序应该遵循如下规则:首先是C库,接下来是C++库,最后是自定义库。

其中C库和C++库禁止使用#include "foo",而必须使用#include <foo>

C库必须使用以c开头,不带.h的头文件,旧有的以.h结尾,不带c的头文件不再使用。

禁止使用万能头文件。

#define只能用于定义常量标识符。且为了防止可能出现的问题,不应将值定义为复杂的常量表达式,而只是一个确定的数字。

例:

#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. forwhile语句内只执行一条语句,这时必须将要执行的语句另起一行,且遵循缩进原则。

在嵌套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标识符选择性添加,平时应尽量少用。

为减少全局变量数量,推荐尽量传引用参数。

函数应该用于封装常用数学函数,数据结构常见操作,常用算法等,对于输入输出等简单内容不推荐再使用函数封装。

例如下面做法是不推荐的:

int main()
{
 input();
 solve();
 output();
 return 0;
}

Part 6 结构体与类

算法竞赛中不推荐使用类class,而推荐使用结构体struct

重载运算符在结构体内实现和在结构体外实现都可以接受。

应该使用构造函数初始化结构体与类。

需注意的是,列表初始化为 C++11 标准内容,应根据环境谨慎使用。

例:

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 例子

去看猪国杀吧。