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"
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 namensx/*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).
@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).
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.
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.
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).
@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.
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
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.
Könnten Sie einen Hinweis darauf geben, wo in der C-Norm diese -I
Unternehmen angegeben ist?
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).
Dies ist größtenteils der gleiche Text wie die Antwort von piCookie aus sieben Jahre früher.
@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).
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.
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?