Perché non dovrei #include <bits / stdc ++. H>?
Ho pubblicato una domanda con il mio codice la cui unica #include
direttiva era la seguente:
#include <bits/stdc++.h>
Il mio insegnante mi ha detto di farlo, ma nella sezione commenti sono stato informato che non avrei dovuto.
Perché?
Risposte
L'inclusione <bits/stdc++.h>
sembra essere una cosa sempre più comune da vedere su Stack Overflow, forse qualcosa di appena aggiunto a un curriculum nazionale nell'anno accademico in corso.
Immagino che i vantaggi siano dati vagamente in questo modo:
- Hai solo bisogno di scrivere una
#include
riga - Non è necessario cercare in quale intestazione standard si trova tutto
Sfortunatamente, questo è un trucco pigro, che nomina direttamente un'intestazione interna di GCC invece di singole intestazioni standard come <string>
, <iostream>
e <vector>
. Rovina la portabilità e favorisce terribili abitudini.
Gli svantaggi includono:
- Probabilmente funzionerà solo su quel compilatore
- Non hai idea di cosa farà quando lo usi, perché i suoi contenuti non sono fissati da uno standard
- Anche il solo aggiornamento del compilatore alla versione successiva potrebbe interrompere il programma
- Ogni singola intestazione standard deve essere analizzata e compilata insieme al codice sorgente, che è lento e si traduce in un eseguibile ingombrante con determinate impostazioni di compilazione
Non farlo!
Maggiori informazioni:
- #include <bits / stdc ++. h> con Visual Studio non viene compilato
- Come funziona #include <bits / stdc ++. H> in C ++?
Esempio del motivo per cui Quora è cattivo:
Perché? Perché è usato come se dovesse essere un'intestazione standard C ++, ma nessuno standard lo menziona. Quindi il tuo codice non è portabile per costruzione. Non troverai alcuna documentazione per questo su cppreference . Quindi potrebbe anche non esistere. È frutto dell'immaginazione di qualcuno :)
Ho scoperto - con mio orrore e incredulità - che esiste un noto sito di tutorial in cui ogni esempio C ++ sembra includere questa intestazione . Il mondo è pazzo. Questa è la prova.
A chiunque stia scrivendo tali "tutorial"
Smetti di usare questa intestazione. Dimenticalo. Non propagare questa follia. Se non sei disposto a capire perché fare questo è sbagliato , credimi sulla parola. Non mi va bene essere trattato come una figura di autorità su qualsiasi cosa, e probabilmente ne sono pieno metà del tempo, ma solo in questo caso farò un'eccezione. Affermo di sapere di cosa sto parlando qui. Credimi sulla parola. Ti imploro.
PS Posso ben immaginare l'abominevole "norma di insegnamento" in cui questa idea malvagia potrebbe aver avuto luogo, e le circostanze che l'hanno condotta. Solo perché sembrava esserci una necessità pratica non lo rende accettabile, nemmeno in retrospettiva.
PPS No, non ce n'era bisogno pratico. Non ci sono molte intestazioni standard C ++ e sono ben documentate. Se insegni, stai rendendo un disservizio ai tuoi studenti aggiungendo tale "magia". Produrre programmatori con una mentalità magica è l'ultima cosa che vogliamo. Se è necessario offrire agli studenti un sottoinsieme di C ++ per semplificare la loro vita, basta produrre un volantino con il breve elenco di intestazioni applicabili al corso in cui insegni e con una documentazione concisa per i costrutti della libreria che ti aspetti che gli studenti utilizzino.
C'è un sito Stack Exchange chiamato Programming Puzzles & Code Golf . I puzzle di programmazione su quel sito si adattano a questa definizione di puzzle :
un giocattolo, un problema o un altro congegno progettato per divertire presentando difficoltà che devono essere risolte con l'ingegnosità o lo sforzo paziente.
Sono progettati per divertire, e non nel modo in cui un programmatore funzionante potrebbe essere divertito da un problema del mondo reale incontrato nel suo lavoro quotidiano.
Code Golf è "un tipo di competizione di programmazione per computer ricreativa in cui i partecipanti si sforzano di ottenere il codice sorgente più breve possibile che implementa un certo algoritmo". Nelle risposte sul sito PP&CG, vedrai le persone specificare il numero di byte nelle loro risposte. Quando trovano un modo per radere qualche byte, cancellano il numero originale e registrano quello nuovo.
Come ci si potrebbe aspettare, il golf in codice premia l'abuso estremo del linguaggio di programmazione. Nomi di variabili di una lettera. Nessuno spazio bianco. Uso creativo delle funzioni di libreria. Caratteristiche non documentate. Pratiche di programmazione non standard. Hack spaventosi.
Se un programmatore inviava una richiesta pull al lavoro contenente codice in stile golf, sarebbe stata rifiutata. I loro colleghi avrebbero riso di loro. Il loro manager sarebbe passato dalla loro scrivania per una chiacchierata. Anche così, i programmatori si divertono a inviare risposte a PP&CG.
Con cosa c'entra stdc++.h
? Come altri hanno sottolineato, usarlo è pigro. Non è portatile, quindi non sai se funzionerà sul tuo compilatore o sulla prossima versione del tuo compilatore. Favorisce cattive abitudini. Non è standard, quindi il comportamento del tuo programma potrebbe differire da quello che ti aspetti. Può aumentare il tempo di compilazione e la dimensione dell'eseguibile.
Sono tutte obiezioni valide e corrette. Allora perché qualcuno dovrebbe usare questa mostruosità?
Si scopre che ad alcune persone piace programmare i puzzle senza il codice golf . Si riuniscono e competono in eventi come ACM-ICPC, Google Code Jam e Facebook Hacker Cup o su siti come Topcoder e Codeforces. Il loro grado si basa sulla correttezza del programma, sulla velocità di esecuzione e sulla velocità con cui presentano una soluzione. Per massimizzare la velocità di esecuzione, molti partecipanti usano C ++. Per massimizzare la velocità di codifica, alcuni usano stdc++.h
.
Questa è una buona idea? Controlliamo l'elenco degli svantaggi. Portabilità? Non importa poiché questi eventi di codifica utilizzano una specifica versione del compilatore che i concorrenti conoscono in anticipo. Conformità agli standard? Non rilevante per un blocco di codice la cui vita utile è inferiore a un'ora. Tempo di compilazione e dimensione eseguibile? Questi non fanno parte della rubrica del punteggio del concorso.
Quindi ci rimangono cattive abitudini. Questa è un'obiezione valida. Utilizzando questo file di intestazione, i concorrenti evitano la possibilità di apprendere quale file di intestazione standard definisce la funzionalità che stanno utilizzando nel loro programma. Quando scrivono codice del mondo reale (e non lo utilizzano stdc++.h
) dovranno dedicare tempo alla ricerca di queste informazioni, il che significa che saranno meno produttivi. Questo è lo svantaggio di esercitarsi con stdc++.h
.
Ciò solleva la questione del perché valga la pena prendere parte alla programmazione competitiva se incoraggia cattive abitudini come l'utilizzo stdc++.h
e la violazione di altri standard di codifica. Una risposta è che le persone lo fanno per lo stesso motivo per cui pubblicano programmi su PP&CG: alcuni programmatori trovano divertente usare le loro abilità di programmazione in un contesto simile a un gioco.
Quindi la domanda se usare stdc++.h
dipende dal fatto che i vantaggi della velocità di codifica in un concorso di programmazione superino le cattive abitudini che si potrebbero sviluppare usandolo.
Questa domanda chiede: "Perché non dovrei #include <bits/stdc++.h>
?" Mi rendo conto che è stato chiesto e risposto per esprimere un punto, e la risposta accettata vuole essere l'unica vera risposta a questa domanda. Ma la domanda non è "Perché non dovrei #includere <bits/stdc++.h>
nel codice di produzione?" Pertanto, penso che sia ragionevole considerare altri scenari in cui la risposta potrebbe essere diversa.
Da N4606, bozza di lavoro, standard per linguaggio di programmazione C ++:
17.6.1.2 Intestazioni [intestazioni]
Ogni elemento della libreria standard C ++ viene dichiarato o definito (come appropriato) in un'intestazione.
La libreria standard C ++ fornisce 61 intestazioni di libreria C ++, come mostrato nella Tabella 14.
Tabella 14 - Intestazioni della libreria 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>
Non ci sono <bits / stdc ++. H> lì. Ciò non sorprende, poiché le intestazioni <bits / ...> sono dettagli di implementazione e di solito portano un avviso:
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly.
<bits / stdc ++. h> porta anche un avvertimento:
* This is an implementation file for a precompiled header.
Il motivo per cui non utilizziamo:
#include <bits/stdc++.h>
è a causa dell'efficienza. Vorrei fare un'analogia: per quelli di voi che conoscono Java: se chiedeste al vostro istruttore se quanto segue fosse una buona idea, a meno che non sia un cattivo istruttore risponderebbero di no:
import java.*.*
La cosa #include ... fa la stessa cosa fondamentalmente ... Non è l'unico motivo per non usarla, ma è uno dei motivi principali per non usarla. Per un'analogia della vita reale: immagina di avere una biblioteca e di voler prendere in prestito un paio di libri dalla biblioteca, trasferiresti l'intera biblioteca vicino a casa tua ?? Sarebbe costoso e inefficiente. Se ti servono solo 5 libri, beh, allora tirane fuori solo 5 ... Non l'intera libreria .....
#include <bits/stdc++.h>
Sembra comodo per l'aspetto del programma Ho solo bisogno di digitare un'istruzione include e funziona, la stessa cosa con lo spostamento di un'intera libreria, guarda, ho solo bisogno di spostare un'intera libreria invece di 5 libri, uno per uno. Ti sembra conveniente per la persona che deve effettivamente fare il trasloco ?? Non tanto, e indovina quale in C ++ la persona che si sposta sarà il tuo computer ... Il computer non si divertirà a spostare l'intera libreria per ogni file sorgente che scrivi:) .....