Warum sollte ich nicht <bits / stdc ++. H> einschließen?
Ich habe eine Frage mit meinem Code gepostet, dessen einzige #include
Anweisung die folgende war:
#include <bits/stdc++.h>
Mein Lehrer sagte mir, ich solle das tun, aber im Kommentarbereich wurde ich informiert, dass ich das nicht tun sollte.
Warum?
Antworten
Das Einbeziehen <bits/stdc++.h>
scheint bei Stack Overflow immer häufiger vorzukommen, vielleicht etwas, das im laufenden akademischen Jahr neu in einen nationalen Lehrplan aufgenommen wurde.
Ich stelle mir vor, die Vorteile sind vage gegeben:
- Sie müssen nur eine
#include
Zeile schreiben - Sie müssen nicht nachsehen, in welchem Standardheader sich alles befindet
Leider ist dies ein fauler Hack, ein GCC internen Header direkt anstelle von einzelnen Standard - Header wie Benennung <string>
, <iostream>
und <vector>
. Es ruiniert die Portabilität und fördert schreckliche Gewohnheiten.
Die Nachteile umfassen:
- Es wird wahrscheinlich nur auf diesem Compiler funktionieren
- Sie haben keine Ahnung, was es tun wird, wenn Sie es verwenden, da sein Inhalt nicht durch einen Standard festgelegt ist
- Selbst ein Upgrade Ihres Compilers auf die nächste Version kann Ihr Programm beschädigen
- Jeder einzelne Standardheader muss zusammen mit Ihrem Quellcode analysiert und kompiliert werden. Dies ist langsam und führt unter bestimmten Kompilierungseinstellungen zu einer umfangreichen ausführbaren Datei
Tu es nicht!
Mehr Informationen:
- #include <bits / stdc ++. h> mit Visual Studio wird nicht kompiliert
- Wie funktioniert #include <bits / stdc ++. H> in C ++?
Beispiel, warum Quora schlecht ist:
Warum? Weil es so verwendet wird, als ob es ein C ++ - Standardheader sein sollte, aber kein Standard erwähnt es. Ihr Code ist also konstruktionsbedingt nicht portierbar. Auf cppreference finden Sie keine Dokumentation dazu . Es könnte also genauso gut nicht existieren. Es ist eine Erfindung der Fantasie von jemandem :)
Zu meinem Entsetzen und Unglauben habe ich festgestellt, dass es eine bekannte Tutorial-Site gibt, auf der jedes C ++ - Beispiel diesen Header zu enthalten scheint . Die Welt ist verrückt. Das ist der Beweis.
An alle, die solche "Tutorials" schreiben
Bitte verwenden Sie diesen Header nicht mehr. Vergiss es. Verbreite diesen Wahnsinn nicht. Wenn Sie nicht verstehen wollen, warum dies falsch ist , nehmen Sie mein Wort dafür. Ich bin nicht in Ordnung, als Autoritätsperson für irgendetwas behandelt zu werden, und ich bin wahrscheinlich die halbe Zeit voll davon, aber ich werde nur in diesem einen Fall eine Ausnahme machen. Ich behaupte, dass ich weiß, wovon ich hier spreche. Nimm mich beim Wort. Ich flehe dich an.
PS Ich kann mir gut vorstellen, welchen abscheulichen "Lehrstandard" diese böse Idee hätte haben können und welche Umstände dazu geführt haben. Nur weil es einen praktischen Bedarf dafür zu geben schien, ist dies nicht akzeptabel - auch nicht im Nachhinein.
PPS Nein, es gab keine praktische Notwendigkeit dafür. Es gibt nicht so viele C ++ - Standardheader und sie sind gut dokumentiert. Wenn Sie unterrichten, tun Sie Ihren Schülern einen schlechten Dienst, indem Sie solche "Magie" hinzufügen. Programmierer mit einer magischen Denkweise zu produzieren, ist das Letzte, was wir wollen. Wenn Sie den Schülern eine Teilmenge von C ++ anbieten müssen, um ihnen das Leben zu erleichtern, erstellen Sie einfach ein Handout mit der kurzen Liste der Überschriften, die für den von Ihnen unterrichteten Kurs gelten, und einer präzisen Dokumentation der Bibliothekskonstrukte, die die Schüler verwenden sollen.
Es gibt eine Stack Exchange-Site namens Programming Puzzles & Code Golf . Die Programmierpuzzles auf dieser Site passen zu dieser Definition von Puzzle :
ein Spielzeug, ein Problem oder eine andere Einrichtung, die amüsieren soll, indem sie Schwierigkeiten aufzeigt, die durch Einfallsreichtum oder geduldige Anstrengung gelöst werden können.
Sie sollen amüsieren und nicht so, wie ein arbeitender Programmierer sich über ein reales Problem amüsieren könnte, das bei seiner täglichen Arbeit auftritt.
Code Golf ist "eine Art Freizeit-Computerprogrammierwettbewerb, bei dem die Teilnehmer versuchen, den kürzestmöglichen Quellcode zu erreichen, der einen bestimmten Algorithmus implementiert." In den Antworten auf der PP & CG-Site sehen Sie, wie Personen die Anzahl der Bytes in ihren Antworten angeben. Wenn sie einen Weg finden, ein paar Bytes zu rasieren, streichen sie die ursprüngliche Nummer aus und zeichnen die neue auf.
Wie zu erwarten ist, belohnt Code-Golf extremen Missbrauch von Programmiersprachen. Ein-Buchstaben-Variablennamen. Kein Leerzeichen. Kreative Nutzung von Bibliotheksfunktionen. Undokumentierte Funktionen. Nicht standardisierte Programmierpraktiken. Schreckliche Hacks.
Wenn ein Programmierer bei der Arbeit eine Pull-Anfrage mit Golf-Code einreichte, wurde diese abgelehnt. Ihre Mitarbeiter würden sie auslachen. Ihr Manager würde an ihrem Schreibtisch vorbeischauen, um sich zu unterhalten. Trotzdem amüsieren sich Programmierer, indem sie Antworten an PP & CG senden.
Was hat das damit zu tun stdc++.h
? Wie andere betont haben, ist die Verwendung faul. Es ist nicht portierbar, sodass Sie nicht wissen, ob es auf Ihrem Compiler oder der nächsten Version Ihres Compilers funktioniert. Es fördert schlechte Gewohnheiten. Es ist nicht Standard, daher kann das Verhalten Ihres Programms von Ihren Erwartungen abweichen. Dies kann die Kompilierungszeit und die Größe der ausführbaren Datei erhöhen.
Dies sind alles gültige und korrekte Einwände. Warum sollte jemand diese Monstrosität nutzen?
Es stellt sich heraus, dass manche Leute gerne Rätsel ohne den Code Golf programmieren . Sie treffen sich und treten bei Veranstaltungen wie ACM-ICPC, Google Code Jam und Facebook Hacker Cup oder auf Websites wie Topcoder und Codeforces an. Ihr Rang basiert auf der Programmkorrektheit, der Ausführungsgeschwindigkeit und der Geschwindigkeit, mit der sie eine Lösung einreichen. Um die Ausführungsgeschwindigkeit zu maximieren, verwenden viele Teilnehmer C ++. Um die Codierungsgeschwindigkeit zu maximieren, verwenden einige von ihnen stdc++.h
.
Ist das eine gute Idee? Lassen Sie uns die Liste der Nachteile überprüfen. Portabilität? Es spielt keine Rolle, da diese Codierungsereignisse eine bestimmte Compilerversion verwenden, die die Teilnehmer im Voraus kennen. Einhaltung von Standards? Nicht relevant für einen Codeblock, dessen Nutzungsdauer weniger als eine Stunde beträgt. Kompilierzeit und ausführbare Größe? Diese sind nicht Teil der Bewertungsrubrik des Wettbewerbs.
Wir haben also schlechte Gewohnheiten. Dies ist ein berechtigter Einwand. Durch die Verwendung dieser Header-Datei vermeiden Teilnehmer die Möglichkeit zu erfahren, welche Standard-Header-Datei die Funktionalität definiert, die sie in ihrem Programm verwenden. Wenn sie Code aus der realen Welt schreiben (und nicht verwenden stdc++.h
), müssen sie Zeit damit verbringen, diese Informationen nachzuschlagen, was bedeutet, dass sie weniger produktiv sind. Das ist der Nachteil beim Üben stdc++.h
.
Dies wirft die Frage auf, warum es sich überhaupt lohnt, an wettbewerbsorientierten Programmen teilzunehmen, wenn dadurch schlechte Gewohnheiten wie die Verwendung stdc++.h
und Verletzung anderer Codierungsstandards gefördert werden. Eine Antwort ist, dass die Leute dies aus dem gleichen Grund tun, aus dem sie Programme auf PP & CG veröffentlichen: Einige Programmierer finden es angenehm, ihre Codierungsfähigkeiten in einem spielerischen Kontext einzusetzen.
Die Frage, ob verwendet werden soll, stdc++.h
hängt davon ab, ob die Vorteile der Codierungsgeschwindigkeit bei einem Programmierwettbewerb die schlechten Gewohnheiten überwiegen, die man durch die Verwendung entwickeln könnte.
Diese Frage lautet: "Warum sollte ich nicht # einschließen <bits/stdc++.h>
?" Mir ist klar, dass es gefragt und beantwortet wurde, um einen Punkt zu machen, und die akzeptierte Antwort soll die einzig wahre Antwort auf diese Frage sein. Die Frage lautet jedoch nicht "Warum sollte ich nicht # <bits/stdc++.h>
in den Produktionscode aufnehmen?" Daher halte ich es für sinnvoll, andere Szenarien in Betracht zu ziehen, in denen die Antwort möglicherweise anders ist.
Ab N4606, Arbeitsentwurf, Standard für die Programmiersprache C ++:
17.6.1.2 Header [Header]
Jedes Element der C ++ - Standardbibliothek wird in einem Header deklariert oder (entsprechend) definiert.
Die C ++ - Standardbibliothek bietet 61 C ++ - Bibliotheksheader (siehe Tabelle 14).
Tabelle 14 - C ++ - Bibliotheksheader
<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>
Es gibt dort kein <bits / stdc ++. H>. Dies ist nicht überraschend, da <bits / ...> -Header Implementierungsdetails sind und normalerweise eine Warnung enthalten:
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly.
<bits / stdc ++. h> enthält auch eine Warnung:
* This is an implementation file for a precompiled header.
Der Grund, den wir nicht verwenden:
#include <bits/stdc++.h>
liegt an der Effizienz. Lassen Sie mich eine Analogie ziehen: Für diejenigen unter Ihnen, die Java kennen: Wenn Sie Ihren Lehrer fragen, ob Folgendes eine gute Idee ist, würden sie nein sagen, es sei denn, sie sind schlechte Lehrer:
import java.*.*
Das # include ... Ding macht im Grunde das Gleiche ... Das ist nicht der einzige Grund, es nicht zu benutzen, aber es ist einer der Hauptgründe, es nicht zu benutzen. Für eine echte Analogie: Stellen Sie sich vor, Sie hätten eine Bibliothek und wollten ein paar Bücher aus der Bibliothek ausleihen. Würden Sie die gesamte Bibliothek neben Ihr Haus verlegen? Es wäre teuer und ineffizient. Wenn Sie nur 5 Bücher benötigen, nehmen Sie nur 5 heraus ... Nicht die gesamte Bibliothek .....
#include <bits/stdc++.h>
Sieht für das Programm gut aus. Ich muss nur eine include-Anweisung eingeben und es funktioniert, genau wie beim Verschieben einer ganzen Bibliothek. Ich muss nur eine ganze Bibliothek anstelle von 5 Büchern nacheinander verschieben. Sieht für Sie praktisch aus, für die Person, die tatsächlich umziehen muss? Nicht so sehr, und raten Sie mal, was in C ++ die Person ist, die den Umzug ausführt. Ihr Computer wird es nicht genießen, die gesamte Bibliothek für jede Quelldatei zu verschieben, die Sie schreiben :) .....