Worin besteht in den Programmiersprachen C und C++ der Unterschied zwischen der Verwendung von spitzen Klammern und der Verwendung von Anführungszeichen in einer include
Erklärung wie folgt?
#include <filename>
#include "filename"
Worin besteht in den Programmiersprachen C und C++ der Unterschied zwischen der Verwendung von spitzen Klammern und der Verwendung von Anführungszeichen in einer include
Erklärung wie folgt?
#include <filename>
#include "filename"
In der Praxis besteht der Unterschied darin, an welcher Stelle der Präprozessor nach der eingeschlossenen Datei sucht.
Para #include <filename>
der Präprozessor sucht in einer implementierungsabhängigen Weise, normalerweise in vom Compiler/IDE vorgegebenen Suchverzeichnissen. Diese Methode wird normalerweise verwendet, um Header-Dateien der Standardbibliothek einzubinden.
Para #include "filename"
sucht der Präprozessor zuerst im gleichen Verzeichnis wie die Datei, die die Direktive enthält, und folgt dann dem Suchpfad, der für die Direktive #include <filename>
Form. Diese Methode wird normalerweise verwendet, um vom Programmierer definierte Header-Dateien einzubinden.
Eine ausführlichere Beschreibung finden Sie in der GCC Dokumentation über Suchpfade .
Die Anweisung: "der Präprozessor sucht im gleichen Verzeichnis..." mag in der Praxis zutreffen, aber der Standard besagt, dass die benannte Quelldatei "in einer implementierungsdefinierten Weise gesucht wird". Siehe Antwort von piCookie.
Auch wenn Ihre Antwort "richtig" zu sein scheint, weil viele Implementierungen aus Konvention so arbeiten, sollten Sie sich die Antworten von aib und piCookie genau ansehen. Beide weisen darauf hin (unterstützt durch den Wortlaut des C-Standards), dass der eigentliche Unterschied in der Einbindung eines "Headers" im Gegensatz zur Einbindung einer "Quelldatei" besteht (und nein, das bedeutet nicht ".h" vs. ".c"). "Quelldatei" kann in diesem Zusammenhang eine ".h"-Datei sein (und ist es normalerweise auch, und sollte es fast immer sein). Ein Header muss nicht notwendigerweise eine Datei sein (ein Compiler könnte z.B. einen Header einbinden, der statisch kodiert ist und nicht in einer Datei steht).
"... der Präprozessor sucht im gleichen Verzeichnis wie die zu kompilierende Datei nach der einzubindenden Datei." Diese Aussage ist nicht ganz korrekt. Ich habe mich für diese Frage interessiert, weil ich neugierig war, wie die tatsächliche Antwort lautet, aber ich weiß, dass dies nicht stimmt, weil zumindest mit gcc, wenn Sie einen zusätzlichen Include-Pfad mit -I angeben, nach Dateien gesucht wird, die mit #include "Dateiname.h" angegeben sind.
Die einzige Möglichkeit, dies herauszufinden, ist die Lektüre der Dokumentation zu Ihrer Implementierung.
En die C-Norm In Abschnitt 6.10.2, Absätze 2 bis 4 heißt es:
Eine Vorverarbeitungsrichtlinie der Form
#include <h-char-sequence> new-line
sucht in einer Folge von durch die Implementierung definierten Stellen nach einer Kopfzeile eindeutig identifiziert durch die angegebene Reihenfolge zwischen den
<
y>
Begrenzungszeichen und bewirkt die Ersetzung dieser Richtlinie durch den gesamten Inhalt der Datei Kopfzeile . Die Art und Weise, wie die Stellen angegeben oder die Kopfzeile identifiziert wird, ist implementierungsabhängig.Eine Vorverarbeitungsrichtlinie der Form
#include "q-char-sequence" new-line
bewirkt die Ersetzung dieser Richtlinie durch den gesamten Inhalt der Datei Quelldatei identifiziert durch die angegebene Reihenfolge zwischen den
"
Begrenzungszeichen. Die benannten Quelldatei wird auf eine durch die Implementierung festgelegte Weise gesucht. Wird diese Suche nicht unterstützt oder schlägt die Suche fehl, wird die Richtlinie erneut verarbeitet, als ob sie lautet#include <h-char-sequence> new-line
mit der identischen enthaltenen Sequenz (einschließlich
>
Zeichen, falls vorhanden) aus dem Original Richtlinie.Eine Vorverarbeitungsrichtlinie der Form
#include pp-tokens new-line
(die nicht mit einer der beiden vorherigen Formen übereinstimmt) ist zulässig. Die Vorverarbeitungs-Token nach
include
in der Richtlinie werden genau wie normaler Text verarbeitet. (Jeder Bezeichner, der gegenwärtig als Makroname definiert ist, wird durch seine Ersetzungsliste von Vorverarbeitungs-Tokens ersetzt.) Die Richtlinie, die sich nach allen Ersetzungen ergibt, muss einer der beiden vorherigen Formen entsprechen. Die Methode, mit der eine Folge von Vorverarbeitungszeichen zwischen einer<
und eine>
Vorverarbeitungs-Token-Paar oder ein Paar von"
Zeichen zu einem einzigen Vorverarbeitungs-Token für den Kopfnamen kombiniert wird, ist implementierungsabhängig.Definitionen:
h-char: jedes Mitglied des Quellzeichensatzes mit Ausnahme des Zeilenumbruchs und
>
q-char: jedes Mitglied des Quellzeichensatzes mit Ausnahme des Zeilenumbruchs und
"
@piCookie sowohl <Dateiname> als auch "Dateiname" suchen nach in der Implementierung definierten Orten. Worin besteht also der Unterschied?
@entropy: In einem Forum wie diesem ist es nicht möglich, Ihre Frage zu beantworten. Eine Antwort, die für einen bestimmten Compiler richtig wäre, könnte für einen anderen völlig falsch sein. Jede einzelne Implementierung/jeder einzelne Compiler sollte verpflichtet sein, den Unterschied zu erläutern, und das ist der einzige verlässliche Weg, dies zu wissen. In mehreren anderen Antworten wurden Beispiele genannt, und vielleicht wird Ihre Implementierung in einer dieser Antworten erwähnt.
Die Zeichenfolge zwischen < und > verweist eindeutig auf einen Header, der nicht unbedingt eine Datei ist. Den Implementierungen steht es ziemlich frei, die Zeichenfolge zu verwenden, wie sie wollen. (Meistens wird sie jedoch einfach als Dateiname behandelt und eine Suche in der Include-Pfad wie in den anderen Beiträgen erwähnt).
Wenn die #include "file"
Form verwendet wird, sucht die Implementierung zunächst nach einer Datei mit dem angegebenen Namen, sofern dies unterstützt wird. Falls nicht (unterstützt) oder falls die Suche fehlschlägt, verhält sich die Implementierung so, als ob die andere ( #include <file>
) Form verwendet wurde.
Außerdem gibt es eine dritte Form, die verwendet wird, wenn die #include
Richtlinie entspricht keiner der obigen Formen. In dieser Form werden einige grundlegende Vorverarbeitungen (wie die Makroexpansion) an den "Operanden" der Direktive #include
und es wird erwartet, dass das Ergebnis einer der beiden anderen Formen entspricht.
+1, dies ist wahrscheinlich die prägnanteste und korrekteste Antwort. Laut der Norm (aus der piCookie in seiner Antwort zitiert) ist die einzige real Der Unterschied besteht zwischen "Header" und "Quelldatei". Der Suchmechanismus ist in beiden Fällen implementierungsabhängig. Die Verwendung von Anführungszeichen bedeutet, dass Sie eine "Quelldatei" einschließen wollen, während spitze Klammern bedeuten, dass Sie einen "Header" einschließen wollen, der, wie Sie sagen, möglicherweise gar keine Datei ist.
Ich weiß, dass ich diese Frage erst lange nach Ihrer Antwort stelle, aber @aib, was meinen Sie mit "eindeutig auf einen Header verweisen, der nicht unbedingt eine Datei ist"? Auch Header-Dateien sind Dateien!
Siehe Dan Mouldings Kommentar zu quest49s Antwort; Standard-Header müssen nicht in Dateiform vorliegen, sie können eingebaut sein.
Einige gute Antworten verweisen hier auf den C-Standard, vergessen aber den POSIX-Standard, insbesondere das spezifische Verhalten der c99 (z.B. C-Compiler) Befehl.
Nach Angaben von The Open Group Base Specifications Ausgabe 7 ,
-I Verzeichnis
Ändern Sie den Algorithmus für die Suche nach Kopfzeilen, deren Namen keine absoluten Pfadnamen sind, um in dem Verzeichnis zu suchen, das durch die Option Verzeichnis Pfadnamen, bevor Sie an den üblichen Stellen suchen. So werden Kopfzeilen, deren Namen in doppelten Anführungszeichen ( "" ) stehen, zuerst im Verzeichnis der Datei mit dem #include Zeile, dann in Verzeichnissen, die in -I Optionen, und zuletzt an den üblichen Stellen. Bei Kopfzeilen, deren Namen in spitze Klammern ("<>") eingeschlossen sind, wird die Kopfzeile nur in Verzeichnissen gesucht, die in -I Optionen und dann an den üblichen Stellen. Verzeichnisse, die in -I Die Optionen werden in der angegebenen Reihenfolge durchsucht. Die Implementierungen müssen mindestens zehn Instanzen dieser Option in einer einzigen c99 Befehlsaufruf.
In einer POSIX-kompatiblen Umgebung und mit einem POSIX-kompatiblen C-Compiler, #include "file.h"
wird wahrscheinlich suchen nach ./file.h
zuerst, wobei .
ist das Verzeichnis, in dem sich die Datei mit dem #include
Anweisung, während #include <file.h>
wird wahrscheinlich suchen nach /usr/include/file.h
zuerst, wobei /usr/include
ist Ihr System definiert übliche Orte für Kopfzeilen (sie ist anscheinend nicht durch POSIX definiert).
Was ist die genaue Quelle des Textes? Stammt er aus dem normativen Teil von IEEE Std 1003.1, 2013?
@osgx: Diese Formulierung (oder eine sehr ähnliche) findet sich in der POSIX-Spezifikation für c99
- was der POSIX-Name für den C-Compiler ist. (Der POSIX-Standard von 2008 konnte sich kaum auf C11 beziehen; die Aktualisierung von POSIX 2008 im Jahr 2013 hat den C-Standard, auf den er sich bezog, nicht geändert).
Das genaue Verhalten des Präprozessors ist von Compiler zu Compiler unterschiedlich. Die folgende Antwort gilt für GCC und einige andere Compiler.
#include <file.h>
weist den Compiler an, in seinem "includes"-Verzeichnis nach dem Header zu suchen, z.B. würde der Compiler für MinGW nach file.h
en C:\MinGW\include\ oder wo auch immer Ihr Compiler installiert ist.
#include "file"
weist den Compiler an, das aktuelle Verzeichnis (d. h. das Verzeichnis, in dem sich die Quelldatei befindet) zu durchsuchen nach file
.
Sie können die -I
Flag für GCC, um ihm mitzuteilen, dass er, wenn er auf ein Include mit eckigen Klammern stößt, auch nach Headern im Verzeichnis nach -I
. GCC wird das Verzeichnis nach dem Flag so behandeln, als wäre es das includes
Verzeichnis.
Wenn Sie zum Beispiel eine Datei namens myheader.h
in Ihrem eigenen Verzeichnis, könnten Sie sagen #include <myheader.h>
wenn Sie den GCC mit dem Flag -I .
(was bedeutet, dass im aktuellen Verzeichnis nach Includes gesucht werden soll).
Ohne die -I
Flagge, müssen Sie die #include "myheader.h"
um die Datei einzuschließen, oder verschieben Sie myheader.h
zum include
Verzeichnis Ihres Compilers.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
25 Stimmen
gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC6
2 Stimmen
Wo sucht der GCC seine Header-Dateien
3 Stimmen
Für das Verhalten von Visual Studio, überprüfen Sie bitte: docs.microsoft.com/de-us/cpp/preprocessor/
1 Stimmen
Warum gibt es auf diese Frage noch keine akzeptierte Antwort?
1 Stimmen
Wie solche Frage haben so viel upvote? ist es mit Abstimmung Regeln?