language - what is a c++ header file




Qual è la differenza tra#include<filename> e#include "nomefile"? (20)

Nei linguaggi di programmazione C e C ++, qual è la differenza tra l'uso di parentesi angolari e l'uso di virgolette in un'istruzione di include , come segue?

  1. #include <filename>
  2. #include "filename"

il "<filename>" cerca nelle posizioni delle librerie C standard

mentre "filename" cerca anche nella directory corrente.

Idealmente, dovresti usare <...> per le librerie C standard e "..." per le librerie che scrivi e sono presenti nella directory corrente.


#include <filename>

viene utilizzato quando si desidera utilizzare il file di intestazione del sistema C / C ++ o le librerie del compilatore. Queste librerie possono essere stdio.h, string.h, math.h, ecc.

#include "path-to-file/filename"

viene utilizzato quando si desidera utilizzare il proprio file di intestazione personalizzato che si trova nella cartella del progetto o da qualche altra parte.

Per ulteriori informazioni sui preprocessori e l'intestazione. Leggi C - Preprocessors .


Alcune buone risposte qui fanno riferimento allo standard C ma hanno dimenticato lo standard POSIX, in particolare il comportamento specifico del comando c99 (ad esempio, compilatore C) .

Secondo The Open Group Base Specifications numero 7 ,

-I directory

Modificare l'algoritmo per la ricerca di intestazioni i cui nomi non sono nomi assoluti da cercare nella directory indicata dal nome di percorso della directory prima di cercare nei soliti posti. Pertanto, le intestazioni i cui nomi sono racchiusi tra virgolette ("") devono essere cercati per primi nella directory del file con la riga #include , quindi nelle directory denominate in -I opzioni e l'ultima nei soliti posti. Per le intestazioni i cui nomi sono racchiusi tra parentesi angolari ("<>"), l'intestazione deve essere cercata solo nelle directory denominate in -I opzioni e quindi nei soliti posti. Le directory denominate in -I opzioni devono essere ricercate nell'ordine specificato. Le implementazioni supportano almeno dieci istanze di questa opzione in una singola chiamata di comando c99 .

Quindi, in un ambiente conforme a POSIX, con un compilatore C compatibile con POSIX, #include "file.h" probabilmente ./file.h prima, dove . è la directory in cui è il file con l'istruzione #include , mentre #include <file.h> , è probabile che prima /usr/include/file.h , dove /usr/include è il tuo sistema definito come intestazioni (sembra non definito da POSIX).


Almeno per la versione GCC <= 3.0, il modulo parentesi angolare non genera una dipendenza tra il file incluso e quello incluso.

Pertanto, se si desidera generare regole di dipendenza (utilizzando l'opzione GCC -M per l'esempio), è necessario utilizzare il modulo quotato per i file che devono essere inclusi nell'albero delle dipendenze.

(Vedi http://gcc.gnu.org/onlinedocs/cpp/Invocation.html )


Il #include <filename> viene utilizzato quando si fa riferimento a un file di sistema. Questo è un file di intestazione che può essere trovato in posizioni predefinite di sistema come /usr/include o /usr/local/include .Per i tuoi file che devono essere inclusi in un altro programma devi usare la #include "filename"sintassi.


Il <file> include dice al preprocessore di cercare nelle directory -I e nelle directory predefinite prima , quindi nella directory del file .c. Il "file" include dice al preprocessore di cercare prima la directory del file sorgente e poi tornare a -I e predefinito. Tutte le destinazioni vengono cercate comunque, solo l'ordine di ricerca è diverso.

Lo standard del 2011 riguarda principalmente i file di inclusione in "16.2 Inclusione del file di origine".

2 Una direttiva di pre-elaborazione del modulo

# include <h-char-sequence> new-line

ricerca una sequenza di luoghi definiti dall'implementazione per un'intestazione identificata univocamente dalla sequenza specificata tra i delimitatori <e> e causa la sostituzione di tale direttiva con l'intero contenuto dell'intestazione. Come vengono specificati i posti o l'intestazione identificata è definita dall'implementazione.

3 Una direttiva di pre-elaborazione del modulo

# include "q-char-sequence" new-line

causa la sostituzione di tale direttiva con l'intero contenuto del file di origine identificato dalla sequenza specificata tra i "delimitatori" Il file di origine denominato viene cercato in un modo definito dall'implementazione. Se questa ricerca non è supportata o se la ricerca non riesce , la direttiva viene rielaborata come se leggesse

# include <h-char-sequence> new-line

con la sequenza identica contenuta (compresi i caratteri, se ce ne sono) dalla direttiva originale.

Si noti che il formato "xxx" riduce a <xxx> modulo se il file non viene trovato. Il resto è definito dall'implementazione.


In pratica, la differenza si trova nella posizione in cui il preprocessore cerca il file incluso.

Per #include <filename> le ricerche del preprocessore dipendono dall'implementazione, normalmente nelle directory di ricerca predefinite dal compilatore / IDE. Questo metodo viene normalmente utilizzato per includere file di intestazione di libreria standard.

Per #include "filename" il preprocessore esegue prima la ricerca nella stessa directory del file contenente la direttiva, quindi segue il percorso di ricerca utilizzato per il modulo #include <filename> . Questo metodo viene normalmente utilizzato per includere file di intestazione definiti dal programmatore.

Una descrizione più completa è disponibile nella documentazione GCC sui percorsi di ricerca .


L'unico modo per sapere è leggere la documentazione della tua implementazione.

Nello standard C , sezione 6.10.2, i paragrafi da 2 a 4 indicano:

  • Una direttiva di pre-elaborazione del modulo

    #include <h-char-sequence> new-line
    

    ricerca una sequenza di luoghi definiti dall'implementazione per un'intestazione identificata univocamente dalla sequenza specificata tra i delimitatori < e > e causa la sostituzione di tale direttiva con l'intero contenuto dell'intestazione. Come vengono specificati i posti o l'intestazione identificata è definita dall'implementazione.

  • Una direttiva di pre-elaborazione del modulo

    #include "q-char-sequence" new-line
    

    causa la sostituzione di tale direttiva con l'intero contenuto del file di origine identificato dalla sequenza specificata tra i " delimitatori " Il file di origine denominato viene cercato in un modo definito dall'implementazione. Se questa ricerca non è supportata o se la ricerca non riesce , la direttiva viene rielaborata come se leggesse

    #include <h-char-sequence> new-line
    

    con la sequenza identica contenuta (compresi i caratteri, se ce ne sono) dalla direttiva originale.

  • Una direttiva di pre-elaborazione del modulo

    #include pp-tokens new-line
    

    (che non corrisponde a una delle due forme precedenti) è permesso. I token di preelaborazione dopo l' include nella direttiva vengono elaborati esattamente come nel testo normale. (Ogni identificatore attualmente definito come nome macro viene sostituito dall'elenco sostitutivo dei token di preelaborazione). La direttiva risultante dopo tutte le sostituzioni deve corrispondere a uno dei due moduli precedenti. Il metodo con cui una sequenza di token di preelaborazione tra una coppia di token di preelaborazione < e una > o una coppia di " caratteri è combinata in un token di pre-elaborazione del nome di singola intestazione è definita dall'implementazione.

definizioni:

  • h-char: qualsiasi membro del set di caratteri di origine ad eccezione del carattere di nuova riga e >

  • q-char: qualsiasi membro del set di caratteri sorgente ad eccezione del carattere di nuova riga e "


Lo fa:

"mypath/myfile" is short for ./mypath/myfile

con . essere la directory del file in cui è contenuto #include e / o la directory di lavoro corrente del compilatore e / o il percorso_include_predefinito

e

<mypath/myfile> is short for <defaultincludepaths>/mypath/myfile

Se ./ trova in <default_include_paths> , allora non fa differenza.

Se mypath/myfile trova in un'altra directory di inclusione, il comportamento non è definito.


Molte delle risposte qui si concentrano sui percorsi che il compilatore cercherà per trovare il file. Mentre questo è ciò che fa la maggior parte dei compilatori, un compilatore conforme può essere preprogrammato con gli effetti delle intestazioni standard e trattare, ad esempio, #include <list> come switch, e non deve necessariamente esistere come file.

Questo non è puramente ipotetico. C'è almeno un compilatore che funziona in questo modo. Si consiglia di utilizzare #include <xxx> solo con intestazioni standard.


Quando usi #include <nomefile>, il pre-processore cerca il file nella directory dei file di intestazione C \ C ++ (stdio.h \ cstdio, string, vector, ecc.). Ma, quando usi # include "nomefile": prima, il pre-processore cerca il file nella directory corrente, e se non lo trova qui - lo cerca nella directory dei file di intestazione C \ C ++.


Secondo lo standard - sì, sono diversi:

  • Una direttiva di pre-elaborazione del modulo

    #include <h-char-sequence> new-line
    

    ricerca una sequenza di luoghi definiti dall'implementazione per un'intestazione identificata univocamente dalla sequenza specificata tra i delimitatori < e > e causa la sostituzione di tale direttiva con l'intero contenuto dell'intestazione. Come vengono specificati i posti o l'intestazione identificata è definita dall'implementazione.

  • Una direttiva di pre-elaborazione del modulo

    #include "q-char-sequence" new-line
    

    causa la sostituzione di tale direttiva con l'intero contenuto del file di origine identificato dalla sequenza specificata tra i " delimitatori " Il file di origine denominato viene cercato in un modo definito dall'implementazione. Se questa ricerca non è supportata o se la ricerca non riesce , la direttiva viene rielaborata come se leggesse

    #include <h-char-sequence> new-line
    

    con la sequenza identica contenuta (compresi i caratteri, se ce ne sono) dalla direttiva originale.

  • Una direttiva di pre-elaborazione del modulo

    #include pp-tokens new-line
    

    (che non corrisponde a una delle due forme precedenti) è permesso. I token di preelaborazione dopo l' include nella direttiva vengono elaborati esattamente come nel testo normale. (Ogni identificatore attualmente definito come nome macro viene sostituito dall'elenco sostitutivo dei token di preelaborazione). La direttiva risultante dopo tutte le sostituzioni deve corrispondere a uno dei due moduli precedenti. Il metodo con cui una sequenza di token di preelaborazione tra una coppia di token di preelaborazione < e una > o una coppia di " caratteri è combinata in un token di pre-elaborazione del nome di singola intestazione è definita dall'implementazione.

definizioni:

  • h-char: qualsiasi membro del set di caratteri di origine ad eccezione del carattere di nuova riga e >

  • q-char: qualsiasi membro del set di caratteri sorgente ad eccezione del carattere di nuova riga e "

Si noti che lo standard non indica alcuna relazione tra i modi definiti dall'implementazione. Il primo modulo cerca in un modo definito dall'implementazione e l'altro in un modo (possibilmente altro) definito dall'implementazione. Lo standard specifica anche che alcuni file di inclusione devono essere presenti (ad esempio, <stdio.h> ).

Formalmente dovresti leggere il manuale per il tuo compilatore, tuttavia normalmente (per tradizione) il modulo #include "..." cerca nella directory del file in cui è stato trovato prima #include e poi nelle directory che il #include <...> ricerche di modulo (il percorso di inclusione, ad esempio le intestazioni di sistema).


La documentazione GCC dice quanto segue sulla differenza tra i due:

Sia i file di intestazione utente che di sistema sono inclusi utilizzando la direttiva di pre-elaborazione '#include' . Ha due varianti:

#include <file>

Questa variante viene utilizzata per i file di intestazione di sistema. Cerca un file denominato file in un elenco standard di directory di sistema. Puoi anteporre le directory a questo elenco con l'opzione -I (vedi Invocation ).

#include "file"

Questa variante viene utilizzata per i file di intestazione del proprio programma. Cerca un file denominato file prima nella directory contenente il file corrente, quindi nelle directory di preventivo e quindi nelle stesse directory utilizzate per <file> . È possibile anteporre le directory all'elenco delle directory di preventivo con l'opzione -iquote . L'argomento di '#include' , sia delimitato da virgolette o parentesi angolari, si comporta come una costante di stringa in quanto i commenti non vengono riconosciuti ei nomi di macro non vengono espansi. Pertanto, #include <x/*y> specifica l'inclusione di un file di intestazione di sistema chiamato x/*y .

Tuttavia, se i backslash si verificano all'interno del file, sono considerati normali caratteri di testo, non caratteri di escape. Nessuna delle sequenze di escape dei caratteri appropriate alle costanti stringa in C vengono elaborate. Pertanto, #include "x\n\\y" specifica un nome file contenente tre barre rovesciate. (Alcuni sistemi interpretano '\' come un separatore di pathname, tutti interpretano anche '/' allo stesso modo. È molto più semplice usare solo '/' .)

È un errore se c'è qualcosa (diverso dai commenti) sulla linea dopo il nome del file.


#include <file.h> dice al compilatore di cercare l'intestazione nella sua directory "include", ad esempio per MinGW il compilatore file.h in C: \ MinGW \ include \ o ovunque sia installato il compilatore.

#include "file" dice al compilatore di cercare la directory corrente (cioè la directory in cui risiede il file sorgente) per il file .

Puoi usare il flag -I per GCC per dire che, quando incontra una inclusione con parentesi angolate, dovrebbe cercare anche le intestazioni nella directory dopo -I . GCC tratterà la directory dopo il flag come se fosse la directory includes .

Ad esempio, se hai un file chiamato myheader.h nella tua stessa directory, potresti dire #include <myheader.h> se hai chiamato GCC con il flag -I . (indica che dovrebbe cercare include nella directory corrente).

Senza il flag -I , dovrai usare #include "myheader.h" per includere il file, o spostare myheader.h nella directory include del tuo compilatore.


Credo che le intestazioni incluse tra virgolette vengano cercate negli stessi percorsi di sistema delle parentesi graffe angolari se non vengono trovate nella directory corrente.


Esistono due modi per scrivere #include statement. Questi sono:

#include"filename"
#include<filename>

Il significato di ogni forma è

#include"mylib.h"

Questo comando dovrebbe cercare il file mylib.hnella directory corrente e l'elenco di directory specificato come indicato nel percorso di ricerca incluso che potrebbe essere stato impostato.

#include<mylib.h>

Questo comando dovrebbe cercare il file mylib.hsolo nell'elenco delle directory specificato.

Il percorso di ricerca include non è altro che un elenco di directory in cui cercare il file che viene incluso. I compilatori C differenti consentono di impostare il percorso di ricerca in modi diversi.


La semplice regola generale consiste nell'utilizzare parentesi angolari per includere i file di intestazione forniti con il compilatore. Usa le virgolette per includere qualsiasi altro file di intestazione. La maggior parte dei compilatori lo fa in questo modo.

1.9 - I file di intestazione spiegano in maggior dettaglio le direttive del pre-processore. Se sei un programmatore alle prime armi, quella pagina dovrebbe aiutarti a capire tutto questo. L'ho imparato da qui e l'ho seguito al lavoro.


Per vedere l'ordine di ricerca sul tuo sistema utilizzando gcc, in base alla configurazione corrente, puoi eseguire il seguente comando. Puoi trovare maggiori dettagli su questo comando qui

cpp -v /dev/null -o /dev/null

Apple LLVM versione 10.0.0 (clang-1000.10.44.2)
Destinazione: x86_64-apple-darwin18.0.0
Modello di discussione: posix InstalledDir: Library / Developer / CommandLineTools / usr / bin
"/ Libreria / Sviluppatore / CommandLineTools / usr / bin / clang" -cc1-triple x86_64-apple-macosx10.14.0 -Wdeprecated-objc-isa-usage -Werror = deprecated-objc-isa-usage -E -disable-free - disable-llvm-verifier -discard-value-names -main-nome-file null -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -fno-strict-return -masm-verbose - munwind-tables -target-cpu penryn -dwarf-column-info -debugger-tuning = lldb -target-linker-version 409.12 -v -resource-dir /Library/Developer/CommandLineTools/usr/lib/clang/10.0.0 - isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk -I / usr / local / include -fdebug-compilation-dir / Users / hogstrom -ferror-limit 19 -fmessage-length 80 -stack-protector 1 -fblocks -fencode-extended-block-signature -fobjc-runtime = macosx-10.14.0 -fmax-type-align = 16 -fdiagnostics-show-option -fcolor-diagnostics -traditional-cpp -o - -xc / dev / null
clang -cc1 versione 10.0.0 (clang-1000.10.44.2) destinazione predefinita x86_64-apple-darwin18.0.0 ignorando la directory inesistente "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/local/include" ignorando inesistente directory "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/Library/Frameworks"
#include "..." la ricerca inizia qui:
#include <...> la ricerca inizia qui:
/ usr / local / include
/ Libreria / Sviluppatore / CommandLineTools / usr / lib / clang / 10.0.0 / include
/ Libreria / Sviluppatore / CommandLineTools / usr / include
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include
/ Libreria / Sviluppatore / CommandLineTools / SDKs / MacOSX10.14.sdk / System / Library / Frameworks (directory framework)
Fine della lista di ricerca.


#include "filename" // User defined header
#include <filename> // Standard library header.

Esempio:

Il nome del file qui è Seller.h :

#ifndef SELLER_H     // Header guard
#define SELLER_H     // Header guard

#include <string>
#include <iostream>
#include <iomanip>

class Seller
{
    private:
        char name[31];
        double sales_total;

    public:
        Seller();
        Seller(char[], double);
        char*getName();

#endif

Nell'implementazione della classe (ad esempio, Seller.cpp e in altri file che utilizzeranno il file Seller.h ), l'intestazione definita dall'utente deve ora essere inclusa, come indicato di seguito:

#include "Seller.h"

#include <abc.h>

è usato per includere file di libreria standard. Quindi il compilatore controllerà le posizioni in cui risiedono le intestazioni delle librerie standard.

#include "xyz.h"

dirà al compilatore di includere i file di intestazione definiti dall'utente. Quindi il compilatore controllerà questi file di intestazione nella cartella corrente o -I cartelle definite.





c-preprocessor