写给前算法竞赛选手的 C++ 指北¶
圖靈的同學们不允許打 ACM!傷身而且影響你的編碼風格!這樣會讓你四年一個 star 都沒有!——丘成桐(囯內)
众所周知,NOIP/NOI/XCPC 等算法竞赛中,C++ 是最常用的编程语言,甚至没有之一。然而对大部分选手而言,“写得快”有时甚至要比“代码运行得快”更重要。这就导致了一些约定俗成的坏习惯,包括但不限于:
- 压缩空格,如
int a,b;
- 滥用逗号表达式,如
t=a,a=b,b=t;
using namespace std;
#include <bits/stdc++.h>
typedef unsigned long long ull;
#define int long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
int dp[1000005];
- 无责任的
std::ios::sync_with_stdio(false);
使用
等等等等……上面列出的每一条坏习惯都是工程代码中的死罪,但在算法竞赛中却是常见的,将其推崇为“起手式”的人更是大有人在。
还有一些相比之下不那么严重但仍然很坏的坏习惯,包括但不限于:
- 单字符/无意义变量名/函数名,如
a
、aa
、_
等 - 不写注释
等等。以上我们统称“OI 码风”,或者说是更广义的“code smell”概念的一个体现,即字面上理解成“你的代码散发着令人不适的气味”。
另一方面的问题是,算法竞赛选手通常并不了解 C++。这就导致了一些令人喜闻乐见的“C with STL”、“C with std::sort
”、“C with std::vector
”等称呼,这些都是因为选手们并不了解 C++ 的特性,从而无法真正发挥 C++ 的优势。不少人,包括有些无良教培机构,甚至将“学习 C++”和“学习算法竞赛所需要掌握的算法”绑定起来,似乎这就是 C++ 的唯一用途。诚然,在时间相对较短的比赛中,C++ 对算法竞赛选手而言只是一种工具,但仍有相当比例的选手在退役/退赛后继续使用 C++,进而将以前培养的坏习惯带入工程代码中。在现实工程中,保持代码的可读性和可维护性,要比使用某个时间复杂度占优的算法重要一万倍以上。本文旨在帮助前算法竞赛选手们尽快摆脱“OI 码风”,尽早适应工程代码的规范并能写出更优雅的代码。
……所以我不会教你们如何写代码让别人看得懂。但如果你这样写代码,到企业去工作,可能第一个礼拜就被开除了。——翁恺,2022.9.15
这篇指北分为以下几部分。各部分之间相对独立,推荐按照顺序阅读,但当然你可以根据自己的需求选择性阅读。
- I/O 与调试篇:你的 I/O 操作哪里不对劲,以及应该如何优雅地调试
- 模板篇:模板只要背
template <typename T>
就行? - STL 篇:除了
std::sort
和std::vector
,STL 还有哪些好用的东西? - 字符串篇:C++ 的字符串有三种写法,你知道吗?
- 内存篇:为什么
int dp[1000005];
很烂,写int dp[n];
更烂? - 指针与引用篇:引用一时爽,一直引用一直爽?
- 其他篇:一些杂七杂八的东西