跳转至

写给前算法竞赛选手的 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); 使用

等等等等……上面列出的每一条坏习惯都是工程代码中的死罪,但在算法竞赛中却是常见的,将其推崇为“起手式”的人更是大有人在。

还有一些相比之下不那么严重但仍然很坏的坏习惯,包括但不限于:

  • 单字符/无意义变量名/函数名,如 aaa_
  • 不写注释

等等。以上我们统称“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::sortstd::vector,STL 还有哪些好用的东西?
  • 字符串篇:C++ 的字符串有三种写法,你知道吗?
  • 内存篇:为什么 int dp[1000005]; 很烂,写 int dp[n]; 更烂?
  • 指针与引用篇:引用一时爽,一直引用一直爽?
  • 其他篇:一些杂七杂八的东西

评论