3127 Stimmen

Was ist der Unterschied zwischen #include <Dateiname> und #include "Dateiname"?

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?

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

25 Stimmen

2 Stimmen

3 Stimmen

Für das Verhalten von Visual Studio, überprüfen Sie bitte: docs.microsoft.com/de-us/cpp/preprocessor/

61voto

Suraj Jain Punkte 4237

Die GCC-Dokumentation sagt über den Unterschied zwischen den beiden:

Sowohl Benutzer- als auch System-Header-Dateien werden mit der Vorverarbeitungsanweisung ‘#include’ . Es gibt zwei Varianten:

#include <file>

Diese Variante wird für System-Header-Dateien verwendet. Sie sucht nach einer Datei namens file in einer Standardliste von Systemverzeichnissen. Sie können dieser Liste Verzeichnisse vorangestellt werden mit der -I Option (siehe Anrufung ).

#include "file"

Diese Variante wird für Header-Dateien Ihres eigenen Programms verwendet. Sie sucht eine Datei namens file zuerst in dem Verzeichnis, das die aktuelle Datei enthält, dann in den quote-Verzeichnissen und dann in den gleichen Verzeichnissen, die für <file> . Sie können der Liste der Zitatverzeichnisse Verzeichnisse vorangestellt werden mit der -iquote Option. Das Argument von ‘#include’ ob mit Anführungszeichen oder spitzen Klammern begrenzt, verhält sich wie eine String-Konstante, da Kommentare nicht erkannt und Makronamen nicht expandiert werden. Daher, #include <x/*y> spezifiziert die Aufnahme einer System-Header-Datei namens x/*y .

Wenn jedoch Backslashes in einer Datei vorkommen, werden sie als normale Textzeichen und nicht als Escape-Zeichen betrachtet. Keine der Escape-Zeichenfolgen, die für String-Konstanten in C geeignet sind, werden verarbeitet. Daher, #include "x\n\\y" gibt einen Dateinamen mit drei Backslashes an. (Einige Systeme interpretieren '\' als Pfadnamen-Trennzeichen. Alle diese Systeme interpretieren auch ‘/’ auf die gleiche Weise. Am tragbarsten ist es, wenn Sie nur ‘/’ .)

Es ist ein Fehler, wenn sich in der Zeile nach dem Dateinamen irgendetwas befindet (außer Kommentaren).

0 Stimmen

Was ist ein "Angebotsverzeichnis"?

0 Stimmen

@JackM - es gibt 3 Standorte: die #include -ing Datei's aktuelles Verzeichnis die Angebotsverzeichnisse (die Pfade für die Prüfung der #include "foo.h" Stil enthält), und die Systemverzeichnisse (die Pfade für die Prüfung der #include <bar.h> Stil umfasst).

0 Stimmen

Was bedeutet "System" in der Formulierung "System-Header-Datei"? Ich stelle fest, dass Informatiker oft mit dem Wort "System" um sich werfen, und ich kann oft nicht sagen, ob es "Betriebssystem", "Computersystem" oder etwas anderes bedeutet.

52voto

Stefan Steiger Punkte 72861

Das tut sie:

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

con . entweder das Verzeichnis der Datei ist, in der die #include enthalten ist, und/oder das aktuelle Arbeitsverzeichnis des Compilers, und/oder die default_include_paths

y

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

Si ./ ist in <default_include_paths> dann macht das keinen Unterschied.

Si mypath/myfile in einem anderen Include-Verzeichnis liegt, ist das Verhalten undefiniert.

18 Stimmen

Nein, #include "mypath/myfile" ist nicht gleichbedeutend mit #include "./mypath/myfile" . Wie piCookie's Antwort sagt, weisen doppelte Anführungszeichen den Compiler an, auf eine implementierungsdefinierte Art und Weise zu suchen -- was die Suche an den Stellen beinhaltet, die für #include <...> . (Eigentlich ist es wahrscheinlich gleichwertig, aber nur, weil, zum Beispiel, /usr/include/mypath/myfile kann bezeichnet werden als /usr/include/./mypath/myfile -- zumindest auf Unix-ähnlichen Systemen).

1 Stimmen

@Keith Thompson: Stimmt, ich dachte an meine Linux-Box. Offensichtlich könnte es anders sein. Allerdings interpretiert Windows als Nicht-Posix-Betriebssystem in der Praxis auch / als Pfadseparator, und ./ gibt es auch.

1 Stimmen

Die -L dirpath fügt dann die Option dirpath zum defaultincludepaths im Gegensatz zu einer anderen Bedeutung des Wortes . (wie oben erwähnt). Dies hat die erwartete Folge, dass sowohl #include "..." y #include <...> Suche in dirpath

48voto

El <file> include sagt dem Präprozessor, dass er in -I Verzeichnissen und in vordefinierten Verzeichnissen erste und dann in das Verzeichnis der .c-Datei. Die "file" include weist den Präprozessor an, das Verzeichnis der Quelldatei zu durchsuchen erste und kehren dann zurück zu -I und vordefiniert. Alle Ziele werden ohnehin durchsucht, nur die Reihenfolge der Suche ist unterschiedlich.

In der Norm 2011 werden die Include-Dateien hauptsächlich in "16.2 Einbindung von Quelldateien" behandelt.

2 Eine Vorverarbeitungsrichtlinie der Form

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

sucht in einer Folge von durch die Implementierung definierten Stellen nach einer Kopfzeile, die eindeutig durch den Parameter zwischen den Begrenzungszeichen < und > identifiziert wird, und bewirkt die die Ersetzung dieser Richtlinie durch den gesamten Inhalt der Kopfzeile. Wie die Stellen angegeben oder der Header identifiziert wird, ist implementierungsabhängig.

3 Eine Vorverarbeitungsrichtlinie der Form

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

bewirkt die Ersetzung dieser Direktive durch den gesamten Inhalt der Quelldatei, die durch die angegebene Sequenz zwischen den Begrenzungszeichen ". Die benannte Quelldatei wird wird auf eine durch die Implementierung festgelegte Weise gesucht. Wenn diese Suche nicht unterstützt wird oder die Suche fehlschlägt, wird die Direktive erneut verarbeitet, als ob als würde sie lesen

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

mit der identischen enthaltenen Sequenz (einschließlich > Zeichen, falls vorhanden) aus der ursprünglichen Richtlinie.

Beachten Sie, dass "xxx" Form degradiert zu <xxx> Formular, wenn die Datei nicht gefunden wird. Der Rest ist implementierungsabhängig.

7 Stimmen

Könnten Sie einen Hinweis darauf geben, wo in der C-Norm diese -I Unternehmen angegeben ist?

2 Stimmen

Ich sehe keinen Hinweis auf -I .

2 Stimmen

Das ist der "implementierungsdefinierte" Teil.

26voto

skyking Punkte 13037

Nach der Norm - ja, sie sind unterschiedlich:

  • Eine Vorverarbeitungsrichtlinie der Form

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

    sucht in einer Folge von implementierungsdefinierten Stellen nach einer Kopfzeile, die eindeutig durch die angegebene Folge zwischen den < y > Begrenzungszeichen, und bewirkt, dass diese Richtlinie durch den gesamten Inhalt der Kopfzeile ersetzt wird. 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 Direktive durch den gesamten Inhalt der Quelldatei, die durch die angegebene Sequenz zwischen den Zeichen " Begrenzungszeichen. Die benannte Quelldatei wird auf eine durch die Implementierung festgelegte Weise gesucht. Wenn diese Suche nicht unterstützt wird oder wenn die Suche fehlschlägt, wird die Direktive erneut verarbeitet, als ob sie

    #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-Token ersetzt.) Die Richtlinie, die sich nach allen Ersetzungen ergibt, muss mit einer der beiden vorherigen Formen übereinstimmen. 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 "

Es ist zu beachten, dass die Norm keine Beziehung zwischen den durch die Implementierung definierten Arten herstellt. Die erste Form sucht auf eine implementierungsdefinierte Weise, die andere auf eine (möglicherweise andere) implementierungsdefinierte Weise. Der Standard legt auch fest, dass bestimmte Include-Dateien vorhanden sein müssen (zum Beispiel, <stdio.h> ).

Formal müssen Sie das Handbuch Ihres Compilers lesen, aber normalerweise (aus Tradition) ist die #include "..." Formular sucht das Verzeichnis der Datei, in der die #include gefunden wurde, und dann die Verzeichnisse, die der #include <...> Formularsuchen (der Include-Pfad, z. B. System-Header).

3 Stimmen

Dies ist größtenteils der gleiche Text wie die Antwort von piCookie aus sieben Jahre früher.

6 Stimmen

@KyleStrand Das liegt daran, dass der gleiche Text ein Zitat des entsprechenden Abschnitts in der Norm ist - dieser Text sollte identisch sein. Die tatsächliche Antwort ist nicht derselbe Text und ist etwas anders - während ich auch anerkenne, dass es in der Dokumentation für die Implementierung geschrieben wird, stelle ich auch fest, dass es auch eine traditionelle Art und Weise gibt, wie diese interpretiert werden (die die meisten oder alle Compiler, die ich verwendet habe, respektieren).

2 Stimmen

IMO ist dies die beste Antwort, weil sie sowohl das abdeckt, was die Norm sagt, als auch das, was die meisten Compiler tatsächlich tun.

22voto

Denis Ros Punkte 219

Zumindest bei der GCC-Version <= 3.0 erzeugt die spitze Klammerform keine Abhängigkeit zwischen der eingeschlossenen Datei und der einschließenden Datei.

Wenn Sie also Abhängigkeitsregeln generieren wollen (z.B. mit der Option GCC -M), müssen Sie die Dateien, die in den Abhängigkeitsbaum aufgenommen werden sollen, in Anführungszeichen setzen.

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

1 Stimmen

Ja - es gibt verschiedene Möglichkeiten, Abhängigkeiten zu erzeugen. Das ist eine von ihnen, aber nicht die einzige.

CodeJaeger.com

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.

Powered by:

X