Почему мне не следует #include <bits / stdc ++. H>?
Я разместил вопрос со своим кодом, единственная #include
директива которого была следующей:
#include <bits/stdc++.h>
Мой учитель сказал мне сделать это, но в разделе комментариев мне сказали, что я не должен.
Зачем?
Ответы
Включение, <bits/stdc++.h>
похоже, становится все более распространенной вещью в Stack Overflow, возможно, что-то новое, добавленное в национальную учебную программу в текущем учебном году.
Я полагаю, что преимущества смутно описаны таким образом:
- Вам нужно написать только одну
#include
строку - Вам не нужно смотреть, в каком стандартном заголовке все находится
К сожалению, это ленивый прием, который дает имя внутреннему заголовку GCC напрямую вместо отдельных стандартных заголовков, таких как <string>
, <iostream>
и <vector>
. Это портит портативность и порождает ужасные привычки.
К недостаткам можно отнести:
- Вероятно, он будет работать только с этим компилятором
- Вы не представляете, что он будет делать, когда вы его используете, потому что его содержимое не установлено стандартом
- Даже простое обновление вашего компилятора до его собственной следующей версии может сломать вашу программу.
- Каждый стандартный заголовок должен быть проанализирован и скомпилирован вместе с исходным кодом, который работает медленно и приводит к громоздкому исполняемому файлу при определенных настройках компиляции.
Не делай этого!
Дополнительная информация:
- #include <bits / stdc ++. h> с Visual Studio не компилируется
- Как #include <bits / stdc ++. H> работает в C ++?
Пример того, почему Quora плохая:
Зачем? Потому что он используется так, как будто это должен быть стандартный заголовок C ++, но ни один стандарт не упоминает об этом. Таким образом, ваш код не является переносимым по конструкции. Вы не найдете для него никакой документации на cppreference . Так что его могло и не существовать. Это плод чьей-то фантазии :)
Я обнаружил - к своему ужасу и недоверию - что существует известный учебный сайт, где каждый пример C ++, кажется, включает этот заголовок . Мир сошел с ума. Это доказательство.
Всем, кто пишет такие "уроки"
Пожалуйста, прекратите использовать этот заголовок. Забудь об этом. Не пропагандируйте это безумие. Если вы не хотите понимать, почему это неправильно , поверьте мне на слово. Меня вообще не устраивают, когда меня рассматривают как авторитетную фигуру в чем-либо, и я, наверное, полон этого, но я сделаю исключение только в этом одном случае. Я утверждаю, что знаю, о чем здесь говорю. Поверьте мне на слово. Умоляю вас.
PS Я хорошо представляю себе отвратительный «стандарт обучения», в котором могла возникнуть эта злая идея, и обстоятельства, которые к ней привели. Просто потому, что это казалось практической необходимостью, не делает это приемлемым - даже в ретроспективе.
PPS Нет, практической необходимости в этом не было. Стандартных заголовков C ++ не так уж и много, и они хорошо документированы. Если вы преподаете, вы оказываете своим ученикам медвежью услугу, добавляя такое «волшебство». Воспитывать программистов с магическим складом ума - это последнее, чего мы хотим. Если вам нужно предложить студентам подмножество C ++, чтобы облегчить их жизнь, просто подготовьте раздаточный материал с кратким списком заголовков, применимых к курсу, который вы преподаете, и с краткой документацией по конструкциям библиотеки, которые, как вы ожидаете, студенты будут использовать.
Есть сайт обмена стеками под названием Programming Puzzles & Code Golf . В головоломки программирования на этом сайте соответствуют этому определению головоломки :
игрушка, проблема или другое приспособление, предназначенное для развлечения, представляя трудности, которые необходимо решить изобретением или терпеливыми усилиями.
Они созданы для развлечения, а не для того, чтобы работающий программист мог развлечься реальной проблемой, с которой он сталкивается в своей повседневной работе.
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>
?» Я понимаю, что этот вопрос был задан, и на него был дан ответ, чтобы подчеркнуть суть, и принятый ответ призван стать Единственным Истинным Ответом на этот вопрос. Но вопрос не в том, почему я не должен включать #include <bits/stdc++.h>
в производственный код? Поэтому я считаю разумным рассмотреть другие сценарии, в которых ответ может быть другим.
Из N4606, Рабочий проект, Стандарт языка программирования C ++:
17.6.1.2 Заголовки [заголовки]
Каждый элемент стандартной библиотеки 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.
Причина, по которой мы не используем:
#include <bits/stdc++.h>
это из-за эффективности. Позвольте мне провести аналогию: для тех из вас, кто знает Java: если вы спросите своего инструктора, было ли это хорошей идеей, они бы отказались, если только он не плохой инструктор:
import java.*.*
Элемент #include ... в основном делает то же самое ... Это не единственная причина не использовать его, но это одна из основных причин не использовать его. Для аналогии из реальной жизни: представьте, что у вас есть библиотека, и вы хотите взять в библиотеке пару книг. Не могли бы вы переместить всю библиотеку рядом с вашим домом? Это было бы дорого и неэффективно. Если тебе нужно всего 5 книг, то возьми только 5 ... Не всю библиотеку ...
#include <bits/stdc++.h>
Выглядит удобно для программы. Мне нужно ввести только один оператор include, и он работает, то же самое с перемещением всей библиотеки, послушайте, мне нужно перемещать только одну целую библиотеку вместо 5 книг, одну за другой. Выглядит удобно для вас, то есть для человека, который действительно должен делать переезд ?? Не так уж и много, и угадайте, что в C ++ человек, выполняющий перемещение, будет вашим компьютером ... Компьютеру не понравится перемещать всю библиотеку для каждого исходного файла, который вы пишете :) .....