我为什么不#include <bits stdc ++。h =“”>?

时间:2015-08-04 17:57:15

标签: c++ c++11 c++14 c++03 turbo-c++

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

#include <bits/stdc++.h>

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

为什么?

5 个答案:

答案 0 :(得分:211)

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

我认为这些优点含糊不清:

  • 您只需要写一个#include
  • 您无需查找
  • 中的所有标准标题

不幸的是,这是一个懒惰的黑客,直接命名GCC内部标头而不是<string><iostream><vector>等单个标准标头。它破坏了便携性,并养成了可怕的习惯。

缺点包括:

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

不要这样做!

更多信息:

Quora为何不好的例子:

答案 1 :(得分:23)

为什么呢?因为它被用作好像它应该是一个C ++标准头,但没有标准提到它。所以你的代码是不可移植的。您在cppreference上找不到任何相关文档。所以它可能不存在。它是某人想象力的虚构:)

答案 2 :(得分:4)

有一个名为Programming Puzzles & Code Golf的Stack Exchange网站。该站点上的编程难题符合puzzle的定义:“玩具,问题或其他设计,旨在通过提出要通过独创性或耐心努力解决的困难来进行娱乐。”他们的目的是逗乐,而不是使工作中的程序员可能因在日常工作中遇到的现实问题而感到有趣。

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

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

如果程序员在工作中提交包含高尔夫风格代码的拉取请求,该请求将被拒绝。他们的同事会嘲笑他们。他们的经理将坐在他们的办公桌旁聊天。即使这样,程序员也可以通过向PP&CG提交答案来娱乐自己。

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

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

事实证明,有些人喜欢编程拼图,而没有 code golf 。他们聚在一起,参加诸如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>?我意识到有人提出并回答了这个问题,所接受的答案旨在成为该问题的唯一真实答案。但是问题不在于“为什么不应该在生产代码中#include <bits/stdc++.h>?”因此,我认为考虑答案可能不同的其他情况是合理的。

答案 3 :(得分:2)

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

17.6.1.2标头[headers]

  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>

那里没有。这并不奇怪,因为头是实现细节,通常带有警告:

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

也带有警告:

*  This is an implementation file for a precompiled header.

答案 4 :(得分:2)

我们不使用的原因:

#include <bits/stdc++.h>

是因为效率。 让我做个比喻: 对于那些了解Java的人: 如果您问您的讲师,以下内容是否是一个好主意,除非他们是一个不好的讲师,否则他们会拒绝:

import java.*.*

#include ...基本上执行相同的操作...这不是不使用它的唯一原因,但这是不使用它的主要原因之一。 对于现实生活中的类比: 假设您有一个图书馆,想从图书馆借些书,您是否会将整个图书馆搬到房屋旁边?这将是昂贵且无效率的。如果您只需要5本书,那么只需取出5本书...而不是整个图书馆.....

#include <bits/stdc++.h>

看起来很符合程序的外观,我只需要键入一个include语句就可以了,它与移动整个库是一样的,看起来我只需要一个完整的库而不是5本书,就一一移动。看起来很方便,对于实际上需要搬家的人?没那么多,猜想在C ++中执行移动的人将是您的计算机...对于您编写的每个源文件,计算机都不会移动整个库:).....