我用我的代码发布了一个问题,其中唯一的#include指令如下:
#include <bits/stdc++.h>
我的老师告诉我这样做,但在评论区我被告知我不应该这样做。
Why?
我用我的代码发布了一个问题,其中唯一的#include指令如下:
#include <bits/stdc++.h>
我的老师告诉我这样做,但在评论区我被告知我不应该这样做。
Why?
当前回答
我们不使用的原因:
#include <bits/stdc++.h>
是因为效率。 让我打个比方: 了解Java的同学: 如果你问你的教练下面的建议是不是一个好主意,除非他们是一个糟糕的教练,否则他们会说不:
import java.*.*
# include……事情基本上是一样的…这不是不使用它的唯一原因,但它是不使用它的主要原因之一。 打个现实生活的比方: 假设你有一个图书馆,你想从图书馆借几本书,你会把整个图书馆搬到你家旁边吗?这既昂贵又低效。如果你只需要5本书,那就只拿5本……不是整个图书馆.....
#include <bits/stdc++.h>
看起来很方便的程序看,我只需要输入一个包含语句,它工作,同样的事情,移动整个图书馆,看,我只需要移动整个图书馆,而不是5本书,一个接一个。对你来说看起来很方便,对真正需要搬家的人来说??没有那么多,你猜怎么着,在c++中,做移动的人将是你的电脑……计算机不会喜欢为您编写的每个源文件移动整个库:).....
其他回答
正如@Lightness Races in Orbit提到的Quora问题的答案中所解释的那样,在编程比赛的上下文中包含bits/stdc++.h并没有错。可移植性、编译时间和标准化方面的缺点与此无关。在大学编程课上,如果示例代码使用了该包含,情况也是如此。
如果您正在编写产品代码,那么就不要使用它。根据当前正在编写的代码的目的来回切换应该不是什么大问题。
有一个Stack Exchange网站叫做Programming Puzzles & Code Golf。该网站上的编程谜题符合谜题的定义:
玩具,难题:一种玩具、难题或其他设计来娱乐的东西,通过提出需要用聪明才智或耐心努力来解决的困难
设计它们是为了娱乐,而不是像工作中的程序员在日常工作中遇到现实世界的问题时那样感到有趣。
“代码高尔夫”是一种娱乐性的计算机编程比赛,参赛者努力写出实现某种算法的尽可能短的源代码。在PP&CG网站上的答案中,你会看到人们在他们的答案中指定字节数。当他们找到一种方法来减少几个字节时,他们会去掉原来的数字并记录下新的数字。
正如您所期望的,代码高尔夫会导致极端的编程语言滥用。一个字母的变量名。没有空格。创造性地使用图书馆功能。无证功能。非标准编程实践。骇人听闻的黑客。
如果程序员在工作中提交了一个包含高尔夫风格代码的pull请求,它将被拒绝。他们的同事会嘲笑他们。他们的经理会到他们的办公桌旁聊天。即便如此,程序员还是通过向PP&CG提交答案来取乐。
这与stdc++.h有什么关系?正如其他人指出的那样,使用它是懒惰的表现。它是不可移植的,所以你不知道它是否适用于你的编译器或编译器的下一个版本。它会培养坏习惯。它是非标准的,因此您的程序的行为可能与您期望的不同。它可能会增加编译时间和可执行文件大小。
这些都是合理和正确的反对意见。那为什么会有人用这个怪物呢?
事实证明,有些人喜欢编写没有代码的谜题高尔夫。他们聚集在一起,在ACM-ICPC、谷歌Code Jam和Facebook Hacker Cup等活动上竞争,或者在Topcoder和Codeforces等网站上竞争。他们的排名是基于程序的正确性、执行速度以及提交解决方案的速度。为了最大限度地提高执行速度,许多参与者使用c++。为了最大限度地提高编码速度,其中一些使用stdc++.h。
这是个好主意吗?让我们来看看缺点清单。可移植性吗?这没有关系,因为这些编码活动使用的是参赛者事先知道的特定编译器版本。标准的兼容性呢?对于有效寿命小于一小时的代码块来说,这是不相关的。编译时间和可执行文件大小?这些都不是比赛评分标准的一部分。
所以我们留下了坏习惯。这是一个有效的反对意见。通过使用这个头文件,参赛者避免了学习哪个标准头文件定义了他们在程序中使用的功能的机会。当他们在编写真实的代码时(而不是使用stdc++.h),他们将不得不花时间查找这些信息,这意味着他们的工作效率会降低。这是使用stdc++.h练习的缺点。
这就提出了一个问题:如果竞争性编程鼓励了像使用stdc++.h和违反其他编码标准这样的坏习惯,那么它还有什么价值呢?一个答案是,人们这样做的原因与他们在PP&CG上发布程序的原因相同:一些程序员发现在类似游戏的环境中使用他们的编码技能很有趣。
因此,是否使用stdc++.h的问题归结为在编程比赛中编码速度的好处是否超过了使用它可能养成的坏习惯。
这个问题问:“为什么我不应该#包含<bits/stdc++.h>?”我意识到它的提问和回答是为了表明一个观点,而公认的答案是为了成为这个问题的唯一正确答案。但问题不是“为什么我不应该在产品代码中#包含<bits/stdc++.h> ?”因此,我认为考虑其他答案可能不同的情况是合理的。
来自N4606,标准编程语言c++工作草案:
17.6.1.2报头信息[Headers]
c++标准库的每个元素都在头文件中声明或定义(视情况而定)。 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.
如果你的老师是一个ICPC老师,那么他/她是对的,但如果你的老师是一个软件工程老师,他/她可能不是。 两者各有利弊:
使用它可以节省编码时间,但会增加编译时间。 由于它包含大量名称空间,您可能会意外地遇到难以调试的问题。
为什么?因为它被当作c++标准标头使用,但没有标准提到它。所以你的代码在构造上是不可移植的。在cppreference上找不到它的任何文档。所以它还不如不存在。这是某人想象出来的。
我发现——让我感到恐惧和难以置信的是——在一个著名的教程网站上,每个c++示例似乎都包含这个头文件。世界疯了。这就是证明。
对于任何撰写此类“教程”的人
请停止使用此标头。算了吧。不要传播这种疯狂。如果你不愿意理解为什么这样做是错误的,请相信我的话。我不喜欢在任何事情上被当作权威人物,我可能有一半的时间都是这样,但我只在这件事上破例。我说我知道我在说什么。相信我的话。我恳求你。
附注:我可以很好地想象这种邪恶想法可能产生的可恶的“教学标准”,以及导致这种想法的环境。仅仅因为它似乎有实际的需要,并不意味着它就可以被接受——甚至在回想起来也是如此。
P.P.S. No, there was no practical need for it. There aren't that many C++ standard headers, and they are well documented. If you teach, you're doing your students a disservice by adding such "magic". Producing programmers with a magical mindset is the last thing we want. If you need to offer students a subset of C++ to make their life easier, just produce a handout with the short list of headers applicable to the course you teach, and with concise documentation for the library constructs you expect the students to use.