370

我用我的代码发布了一个问题,其唯一#include指令如下:

#include <bits/stdc++.h>

我的老师告诉我这样做,但在评论部分我被告知我不应该这样做。

为什么?

4

5 回答 5

426

包括<bits/stdc++.h>似乎是在 Stack Overflow 上越来越常见的事情,也许是本学年新添加到国家课程中的内容。

我想这些优势是这样模糊地给出的:

  • 你只需要写#include一行。
  • 您无需查找所有内容都在哪个标准标题中。

不幸的是,这是一个懒惰的技巧,直接命名 GCC 内部标头而不是单独的标准标头,如<string>,<iostream><vector>. 它破坏了便携性并养成了糟糕的习惯。

缺点包括:

  • 它可能只适用于该编译器。
  • 你不知道当你使用它时它会做什么,因为它的内容不是由标准设定的。
  • 即使只是将您的编译器升级到它自己的下一个版本也可能会破坏您的程序。
  • 每个标准头文件都必须与源代码一起解析和编译,这很慢,并且在某些编译设置下会导致庞大的可执行文件。

不要这样做!


更多信息:

Quora为什么不好的例子:

于 2015-08-04T17:57:15.130 回答
94

为什么?因为它的使用就好像它应该是一个 C++ 标准头文件,但没有标准提到它。因此,您的代码在构造上是不可移植的。您不会在cppreference上找到任何文档。所以它也可能不存在。这是某人的想象的虚构:)

我发现——令我惊恐和难以置信——有一个著名的教程站点,其中每个 C++ 示例似乎都包含此标头。世界疯了。这就是证据。


对于任何编写此类“教程”的人

请停止使用此标头。忘掉它。不要传播这种疯狂。如果您不愿意理解为什么这样做是错误的,请相信我的话。在任何事情上我都不能被视为权威人物,而且我可能有一半的时间充满了它,但我只会在这种情况下例外。我声称我知道我在这里说的是什么。相信我的话。我恳求你。

PS我完全可以想象这个邪恶想法可能发生的可恶“教学标准”,以及导致它的情况。仅仅因为它似乎有实际需要并不能让人接受——即使回想起来也不行。

PPS 不,没有实际需要。没有那么多 C++ 标准头文件,而且它们有据可查。如果你教书,你就会通过添加这样的“魔法”来伤害你的学生。培养具有神奇思维方式的程序员是我们最不想要的。如果您需要为学生提供 C++ 的子集以使他们的生活更轻松,只需制作一份讲义,其中包含适用于您教授的课程的简短标题列表,以及您希望学生使用的库结构的简明文档。

于 2015-08-06T16:50:24.063 回答
63

有一个名为Programming Puzzles & Code Golf的 Stack Exchange 站点。该网站上的编程难题符合这个难题的定义:

一种玩具、问题或其他设计,旨在通过提出需要通过聪明才智或耐心努力来解决的困难来娱乐。

它们的设计目的是为了逗乐,而不是像在职程序员可能会被日常工作中遇到的现实问题逗乐一样。

Code Golf是“一种娱乐性的计算机编程竞赛,参赛者力争实现实现某种算法的最短源代码”。在 PP&CG 网站上的答案中,您会看到人们在他们的答案中指定字节数。当他们找到一种方法来减少几个字节时,他们会删除原来的数字并记录新的数字。

正如您所料,代码打高尔夫球会奖励极端的编程语言滥用。一个字母的变量名。没有空格。创造性地使用库函数。未记录的功能。非标准编程实践。骇人听闻的骇客。

如果程序员在工作中提交了包含高尔夫风格代码的拉取请求,它将被拒绝。他们的同事会嘲笑他们。他们的经理会到他们的办公桌前聊天。即便如此,程序员还是通过向 PP&CG 提交答案来娱乐自己。

这有什么关系stdc++.h?正如其他人指出的那样,使用它是懒惰的。它是不可移植的,因此您不知道它是否可以在您的编译器或下一版本的编译器上运行。它助长了坏习惯。它是非标准的,因此您的程序的行为可能与您的预期不同。它可能会增加编译时间和可执行文件大小。

这些都是有效和正确的反对意见。那么为什么会有人使用这个怪物呢?

事实证明,有些人喜欢没有代码高尔夫的编程难题。他们聚在一起参加 ACM-ICPC、Google Code Jam 和 Facebook Hacker Cup 等活动,或者在 Topcoder 和 Codeforces 等网站上竞争。他们的排名基于程序的正确性、执行速度以及他们提交解决方案的速度。为了最大限度地提高执行速度,许多参与者使用 C++。为了最大限度地提高编码速度,其中一些使用.stdc++.h

这是个好主意吗?让我们检查一下缺点列表。可移植性?没关系,因为这些编码活动使用参赛者事先知道的特定编译器版本。符合标准?与使用寿命不到一小时的代码块无关。编译时间和可执行文件大小?这些不是比赛评分标准的一部分。

所以我们留下了坏习惯。这是一个有效的反对意见。通过使用这个头文件,参赛者避免了了解哪个标准头文件定义了他们在程序中使用的功能的机会。当他们编写真实世界的代码(而不是使用stdc++.h)时,他们将不得不花时间查找这些信息,这意味着他们的工作效率会降低。这就是练习的缺点stdc++.h

stdc++.h这就提出了一个问题,如果竞争性编程鼓励使用和违反其他编码标准等不良习惯,为什么还值得参与。一个答案是人们这样做的原因与他们在 PP&CG 上发布程序的原因相同:一些程序员发现在类似游戏的环境中使用他们的编码技能很有趣。

因此,是否使用的问题stdc++.h归结为编程竞赛中编码速度的好处是否超过了使用它可能养成的坏习惯。

这个问题问:“我为什么不应该 #include <bits/stdc++.h>?” 我意识到有人提出并回答了这一点,并且接受的答案旨在成为该问题的唯一真实答案。但问题不是“为什么我不应该<bits/stdc++.h>在生产代码中使用#include?” 因此,我认为考虑答案可能不同的其他场景是合理的。

于 2019-04-23T01:09:00.737 回答
23

来自 N4606,工作草案,C++ 编程语言标准:

17.6.1.2 标头[标头]

  1. C++ 标准库的每个元素都在标头中声明或定义(视情况而定)。

  2. C++ 标准库提供了 61 个 C++ 库头文件,如表 14 所示。

表 14 - C++ 库头文件

<algorithm> <future> <numeric> <strstream>
<any> <initializer_list> <optional> <system_error>
<array> <iomanip> <ostream> <thread>
<atomic> <ios> <queue> <tuple>
<bitset> <iosfwd> <random> <type_traits>
<chrono> <iostream> <ratio> <typeindex>
<codecvt> <istream> <regex> <typeinfo>
<complex> <iterator> <scoped_allocator> <unordered_map>
<condition_variable> <limits> <set> <unordered_set>
<deque> <list> <shared_mutex> <utility>
<exception> <locale> <sstream> <valarray>
<execution> <map> <stack> <variant>
<filesystem> <memory> <stdexcept> <vector>
<forward_list> <memory_resorce> <streambuf>
<fstream> <mutex> <string>
<functional> <new> <string_view>

那里没有 <bits/stdc++.h> 。这并不奇怪,因为 <bits/...> 标头是实现细节,通常带有警告:

*  This is an internal header file, included by other library headers.
*  Do not attempt to use it directly. 

<bits/stdc++.h> 还带有警告:

*  This is an implementation file for a precompiled header.
于 2019-11-03T11:39:31.097 回答
5

我们不使用的原因:

#include <bits/stdc++.h>

是因为效率。让我打个比方:对于那些了解 Java 的人:如果你问你的导师以下是否是一个好主意,除非他们是一个糟糕的导师,否则他们会说不:

import java.*.*

#include... 基本上做同样的事情...这不是不使用它的唯一原因,但它是不使用它的主要原因之一。用现实生活中的比喻:假设你有一个图书馆,你想从图书馆借几本书,你会把整个图书馆搬到你家旁边吗?这将是昂贵且低效的。如果你只需要 5 本书,那就只拿出 5 本书……而不是整个图书馆……

#include <bits/stdc++.h>

看起来很方便程序看起来我只需要输入一个包含语句就可以了,移动整个图书馆也是如此,看起来我只需要移动一个整个图书馆而不是 5 本书,一本接一本。对您来说看起来很方便,对于实际必须搬家的人来说?没那么多,猜猜在 C++ 中进行移动的人将是您的计算机...计算机不会喜欢为您编写的每个源文件移动整个库:).....

于 2020-07-08T00:20:13.703 回答