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

#include <bits/stdc++.h>

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

Why?


当前回答

我们不使用的原因:

#include <bits/stdc++.h>

是因为效率。 让我打个比方: 了解Java的同学: 如果你问你的教练下面的建议是不是一个好主意,除非他们是一个糟糕的教练,否则他们会说不:

import java.*.*

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

#include <bits/stdc++.h>

看起来很方便的程序看,我只需要输入一个包含语句,它工作,同样的事情,移动整个图书馆,看,我只需要移动整个图书馆,而不是5本书,一个接一个。对你来说看起来很方便,对真正需要搬家的人来说??没有那么多,你猜怎么着,在c++中,做移动的人将是你的电脑……计算机不会喜欢为您编写的每个源文件移动整个库:).....

其他回答

对我来说最大的问题是包含这个头文件将无法编译。因此,如果它在那里,我将不得不删除它,尝试编译,并添加所需的标准头文件。

我们不使用的原因:

#include <bits/stdc++.h>

是因为效率。 让我打个比方: 了解Java的同学: 如果你问你的教练下面的建议是不是一个好主意,除非他们是一个糟糕的教练,否则他们会说不:

import java.*.*

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

#include <bits/stdc++.h>

看起来很方便的程序看,我只需要输入一个包含语句,它工作,同样的事情,移动整个图书馆,看,我只需要移动整个图书馆,而不是5本书,一个接一个。对你来说看起来很方便,对真正需要搬家的人来说??没有那么多,你猜怎么着,在c++中,做移动的人将是你的电脑……计算机不会喜欢为您编写的每个源文件移动整个库:).....

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

我想好处大概是这样给出的:

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

不幸的是,这是一个懒惰的hack,直接命名GCC内部头,而不是单个标准头,如<string>, <iostream>和<vector>。它破坏了可移植性,养成了糟糕的习惯。

缺点包括:

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

不要这样做!


更多信息:

#include <bits/stdc++.h> with visual studio未编译 #include <bits/stdc++.h>如何在c++中工作?

Quora为什么不好的例子:

在编程比赛中使用#include <bits/stdc++.h>而不是列出很多include是一个很好的实践吗?

通过查看这个头文件,我至少喜欢看到一个可以包含的所有头文件的列表,以及它们属于哪个版本的c++。在这方面它真的很有用。

包含<bits/stdc++.h>有多糟糕,真的吗?

我希望看到一些真实的数据——一些用来比较编译时间和二进制可执行文件大小的数字。这里有一个快速的“hello world”对比测试。

注意:要了解<bits/stdc++.h>头文件的位置,以及其中的内容,请直接跳转到底部标题为“<bits/stdc++.h>在哪里和什么?”的部分。

简介:

包含<bits/stdc++.h> "include all headers"头文件很容易,但是编译相对较慢。

包含<bits/stdc++.h>头文件与gcc/g++编译器一起工作很好(想必llvm clang编译器也一样,因为它们的目标是与gcc兼容),并且

对二进制可执行文件大小没有影响,但是 它要多花4倍的时间来编译!

我的测试

下面是一个c++程序示例:

include_bits_stdc +。保护作用:

// We will test including this header vs NOT including this header
#include <bits/stdc++.h>

#include <iostream>  // For `std::cin`, `std::cout`, `std::endl`, etc.

int main()
{
    printf("Hello ");
    std::cout << "world!\n\n";

    return 0;
}

下面是一些构建和运行命令:

# make a bin dir
mkdir -p bin

# compile, timing how long it takes
time g++ -Wall -Wextra -Werror -O3 -std=c++17 include_bits_stdc++.cpp -o bin/a

# check binary executable size
size bin/a

# run
bin/a

没有#include <bits/stdc++.h>在顶部

如果我按原样运行上面的“compile”命令,下面是我看到的10次编译:

real    0m0.362s
real    0m0.372s
real    0m0.502s
real    0m0.383s
real    0m0.367s
real    0m0.283s
real    0m0.294s
real    0m0.281s
real    0m0.292s
real    0m0.276s

平均编译时间:(0.362 + 0.372 + 0.502 + 0.383 + 0.367 + 0.283 + 0.294 + 0.281 + 0.292 + 0.276)/10 = 0.3412秒。

Size bin/a显示:

text    data     bss     dec     hex filename
2142     656     280    3078     c06 bin/a

在顶部包含<bits/stdc++.h>

编译10次:

real    0m1.398s
real    0m1.006s
real    0m0.952s
real    0m1.331s
real    0m1.549s
real    0m1.454s
real    0m1.417s
real    0m1.541s
real    0m1.546s
real    0m1.558s

平均编译时间:(1.398 + 1.006 + 0.952 + 1.331 + 1.549 + 1.454 + 1.417 + 1.541 + 1.546 + 1.558)/10 = 1.3752秒。

Size bin/a显示:

text    data     bss     dec     hex filename
2142     656     280    3078     c06 bin/a

结论

因此,在gcc/g++编译器中包含头文件可以很好地工作,并且对二进制可执行文件的大小没有影响,但是它需要花费1.3752秒/ 0.3412秒= 4倍的时间来编译!

在哪里和什么是<bits/stdc++.h>?

总结

<bits/stdc++.h>头文件是gcc/g++编译器的一部分。

如果在Linux上,它将位于您本地系统的/usr/include/x86_64- Linux -gnu/c++/8/bits/stdc++.h。

您可以直接在线查看gcc源代码中的文件:gcc/libstdc++-v3/include/precompiled/stdc++.h

通过查看头文件,我至少喜欢看到一个可以包含的所有头文件的列表,以及它们属于哪个版本的c++。在这方面它真的很有用。

细节

如果您在一个具有优秀索引器的IDE中打开上面的代码,例如Eclipse(它拥有我所发现的最好的索引器;它的索引比MS VSCode要好得多),并按Ctrl +单击#include <bits/stdc++.h>行,它将直接跳转到系统上的头文件!在Linux Ubuntu上,它直接跳转到这个路径并打开这个文件:/usr/include/x86_64- Linux -gnu/c++/8/bits/stdc++.h。

您可以直接在gcc源代码中查看该文件的最新版本,在这里:gcc/libstdc++-v3/include/precompiled/stdc++.h。它只是一个头文件,其中包括所有其他头文件!只在一个地方查看所有头文件就能了解它们是什么以及它们包含什么,这是非常有用和有见地的!同样,在Eclipse中,可以轻松地按Ctrl +单击每个包含的头文件,直接跳转到其源代码实现。

下面是gcc编译器包含的完整的、最新的<bits/stdc++.h>头文件。如果您希望将其包含在自己的个人项目中或与其他编译器一起使用,则始终可以复制并粘贴此内容并自己创建此文件。

gcc / libstdc + + v3 / include /预编译/ stdc + + . h:

// C++ includes used for precompiling -*- C++ -*-

// Copyright (C) 2003-2022 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file stdc++.h
 *  This is an implementation file for a precompiled header.
 */

// 17.4.1.2 Headers

// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cwchar>
#include <cwctype>

#if __cplusplus >= 201103L
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdalign>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cuchar>
#endif

// C++
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>

#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <chrono>
#include <codecvt>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#endif

#if __cplusplus >= 201402L
#include <shared_mutex>
#endif

#if __cplusplus >= 201703L
#include <any>
#include <charconv>
// #include <execution>
#include <filesystem>
#include <optional>
#include <memory_resource>
#include <string_view>
#include <variant>
#endif

#if __cplusplus >= 202002L
#include <barrier>
#include <bit>
#include <compare>
#include <concepts>
#if __cpp_impl_coroutine
# include <coroutine>
#endif
#include <latch>
#include <numbers>
#include <ranges>
#include <span>
#include <stop_token>
#include <semaphore>
#include <source_location>
#include <syncstream>
#include <version>
#endif

#if __cplusplus > 202002L
#include <expected>
#include <spanstream>
#if __has_include(<stacktrace>)
# include <stacktrace>
#endif
#include <stdatomic.h>
#endif

另请参阅

https://www.geeksforgeeks.org/bitsstdc-h-c/ this article plagiarizes from Stack Overflow, though; see my comment here: How does #include <bits/stdc++.h> work in C++? [my Questions & Answers] learn what text, data, bss, and dec mean in the size output: Electrical Engineering Stack Exchange: How do I find out at compile time how much of an STM32's Flash memory and dynamic memory (SRAM) is used up? Convert binutils size output from "sysv" format (size --format=sysv my_executable) to "berkeley" format (size --format=berkeley my_executable)

为什么?因为它被当作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.