Was ist in den Programmiersprachen C und C ++ der Unterschied zwischen der Verwendung von spitzen Klammern und der Verwendung von Anführungszeichen in einer include
Anweisung wie folgt?
#include <filename>
#include "filename"
Was ist in den Programmiersprachen C und C ++ der Unterschied zwischen der Verwendung von spitzen Klammern und der Verwendung von Anführungszeichen in einer include
Anweisung wie folgt?
#include <filename>
#include "filename"
Antworten:
In der Praxis liegt der Unterschied in dem Speicherort, an dem der Präprozessor nach der enthaltenen Datei sucht.
Für #include <filename>
die Präprozessorsuche in implementierungsabhängiger Weise, normalerweise in Suchverzeichnissen, die vom Compiler / der IDE vorab festgelegt wurden. Diese Methode wird normalerweise verwendet, um Standard-Bibliotheksheaderdateien einzuschließen.
Für #include "filename"
den Präprozessor sucht zuerst im selben Verzeichnis wie die Datei , die Richtlinie enthält, und dann folgt den Suchpfad für die verwendeten #include <filename>
Form. Diese Methode wird normalerweise verwendet, um vom Programmierer definierte Header-Dateien einzuschließen.
Eine ausführlichere Beschreibung finden Sie in der GCC- Dokumentation zu Suchpfaden .
#include <...>
das auf dem System installierte Paket und #include "..."
die nahe gelegene Repository-Version verwendet. Ich könnte diese rückwärts haben. In beiden Fällen wird dem Include-Schutz im gepackten Header ein Unterstrich vorangestellt. (Es könnte eine Konvention für Pakete sein oder vielleicht eine Möglichkeit, das Vermischen der beiden absichtlich zu verhindern, obwohl Versionsqualifizierer für mich sinnvoller wären.)
Die einzige Möglichkeit, dies zu erfahren, besteht darin, die Dokumentation Ihrer Implementierung zu lesen.
In der C-Norm , Abschnitt 6.10.2, Absätze 2 bis 4 heißt es:
Eine Vorverarbeitungsanweisung des Formulars
#include <h-char-sequence> new-line
Durchsucht eine Folge von implementierungsdefinierten Stellen nach einem Header, der durch die angegebene Reihenfolge zwischen dem
<
und den>
Trennzeichen eindeutig identifiziert wird , und ersetzt diese Anweisung durch den gesamten Inhalt des Headers . Wie die Orte angegeben oder der Header identifiziert werden, ist implementierungsdefiniert.Eine Vorverarbeitungsanweisung des Formulars
#include "q-char-sequence" new-line
bewirkt, dass diese Anweisung durch den gesamten Inhalt der Quelldatei ersetzt wird, der durch die angegebene Reihenfolge zwischen den
"
Trennzeichen gekennzeichnet ist. Die benannte Quelldatei wird implementierungsdefiniert gesucht. Wenn diese Suche nicht unterstützt wird oder wenn die Suche fehlschlägt, wird die Anweisung erneut verarbeitet, als ob sie gelesen würde#include <h-char-sequence> new-line
mit der identischen enthaltenen Sequenz (einschließlich
>
Zeichen, falls vorhanden) aus der ursprünglichen Direktive.Eine Vorverarbeitungsanweisung des Formulars
#include pp-tokens new-line
(das nicht mit einem der beiden vorherigen Formulare übereinstimmt) ist zulässig. Die Vorverarbeitungstoken nach
include
der Direktive werden wie im normalen Text verarbeitet. (Jeder Bezeichner, der derzeit als Makroname definiert ist, wird durch seine Ersetzungsliste von Vorverarbeitungstoken ersetzt.) Die nach allen Ersetzungen resultierende Direktive muss mit einem der beiden vorherigen Formulare übereinstimmen. Die Methode, mit der eine Folge von Vorverarbeitungstoken zwischen einem<
und einem>
Vorverarbeitungstokenpaar oder einem"
Zeichenpaar zu einem Vorverarbeitungstoken mit einem einzelnen Headernamen kombiniert wird, ist implementierungsdefiniert.Definitionen:
h-char: Jedes Mitglied des Quellzeichensatzes mit Ausnahme des Zeilenumbruchs und
>
q-char: Jedes Mitglied des Quellzeichensatzes mit Ausnahme des Zeilenumbruchs und
"
Die Zeichenfolge zwischen <und> bezieht sich eindeutig auf einen Header, der nicht unbedingt eine Datei ist. Implementierungen können die Zeichenfolge so gut wie frei verwenden. (Meistens behandeln Sie es jedoch einfach als Dateinamen und führen eine Suche im Include-Pfad durch , wie in den anderen Posts angegeben.)
Wenn das #include "file"
Formular verwendet wird, sucht die Implementierung zunächst nach einer Datei mit dem angegebenen Namen, sofern dies unterstützt wird. Wenn dies nicht der Fall ist (unterstützt wird) oder wenn die Suche fehlschlägt, verhält sich die Implementierung so, als ob das andere ( #include <file>
) Formular verwendet wurde.
Es gibt auch ein drittes Formular, das verwendet wird, wenn die #include
Direktive keinem der oben genannten Formulare entspricht. In dieser Form werden einige grundlegende Vorverarbeitungen (wie die Makroerweiterung) für die "Operanden" der #include
Direktive durchgeführt, und es wird erwartet, dass das Ergebnis mit einer der beiden anderen Formen übereinstimmt.
<
und >
als Schlüssel zum Indizieren in die Bibliothek verwendet.
Einige gute Antworten beziehen sich hier auf den C-Standard, haben jedoch den POSIX-Standard vergessen, insbesondere das spezifische Verhalten des Befehls c99 (z. B. C-Compiler) .
Gemäß den Open Group Base Specifications, Ausgabe 7 ,
-Ich Verzeichnis
Ändern Sie den Algorithmus für die Suche nach Headern, deren Namen keine absoluten Pfadnamen sind, so, dass sie in dem Verzeichnis suchen, das durch den Verzeichnispfadnamen benannt ist, bevor Sie an den üblichen Stellen suchen. Daher müssen Header, deren Namen in doppelte Anführungszeichen ("") eingeschlossen sind, zuerst im Verzeichnis der Datei mit der Zeile #include , dann in Verzeichnissen mit den Optionen -I und zuletzt an den üblichen Stellen gesucht werden . Bei Überschriften, deren Namen in spitzen Klammern ("<>") eingeschlossen sind, darf die Überschrift nur in Verzeichnissen gesucht werden, die in den Optionen -I und dann an den üblichen Stellen angegeben sind. In -I- Optionen genannte Verzeichnisse werden in der angegebenen Reihenfolge durchsucht.Aufruf des Befehls c99 .
In einer POSIX-kompatiblen Umgebung mit einem POSIX-kompatiblen C-Compiler #include "file.h"
wird wahrscheinlich ./file.h
zuerst gesucht , wo .
sich das Verzeichnis befindet, in dem sich die Datei mit der #include
Anweisung befindet, während #include <file.h>
wahrscheinlich /usr/include/file.h
zuerst gesucht wird , wo /usr/include
Ihr System definiert ist übliche Stellen für Header (es scheint nicht von POSIX definiert zu sein).
c99
- das ist der POSIX-Name für den C-Compiler. (Der POSIX 2008-Standard konnte sich kaum auf C11 beziehen; das Update 2013 auf POSIX 2008 hat den C-Standard, auf den er sich bezog, nicht geändert.)
-L
.
In der GCC-Dokumentation wird Folgendes über den Unterschied zwischen beiden angegeben:
Sowohl Benutzer- als auch Systemheaderdateien werden mithilfe der Vorverarbeitungsanweisung eingeschlossen
‘#include’
. Es gibt zwei Varianten:
#include <file>
Diese Variante wird für Systemheaderdateien verwendet. Es sucht nach einer Datei mit dem Namen file in einer Standardliste von Systemverzeichnissen. Sie können dieser Liste Verzeichnisse mit der
-I
Option voranstellen (siehe Aufruf ).
#include "file"
Diese Variante wird für Header-Dateien Ihres eigenen Programms verwendet. Es sucht nach einer Datei mit dem Namen file zuerst in dem Verzeichnis, das die aktuelle Datei enthält, dann in den Anführungszeichenverzeichnissen und dann in denselben Verzeichnissen, für die sie verwendet wurde
<file>
. Mit der-iquote
Option können Sie der Liste der Angebotsverzeichnisse Verzeichnisse voranstellen . Das Argument‘#include’
, ob durch Anführungszeichen oder spitze Klammern begrenzt, verhält sich wie eine Zeichenfolgenkonstante, da Kommentare nicht erkannt und Makronamen nicht erweitert werden. Gibt daher#include <x/*y>
die Aufnahme einer Systemheaderdatei mit dem Namen anx/*y
.Wenn jedoch in der Datei Backslashes auftreten, werden diese als normale Textzeichen und nicht als Escapezeichen betrachtet. Keine der Zeichenfolgen-Escape-Sequenzen, die für Zeichenfolgenkonstanten in C geeignet sind, wird verarbeitet. Somit
#include "x\n\\y"
gibt einen Dateinamen drei Schrägstriche enthält. (Einige Systeme interpretieren '\' als Pfadnamen-Trennzeichen. Alle diese werden auch auf‘/’
die gleiche Weise interpretiert . Es ist am portabelsten, es nur zu verwenden‘/’
.)Es ist ein Fehler, wenn sich in der Zeile nach dem Dateinamen etwas (außer Kommentaren) befindet.
Es tut:
"mypath/myfile" is short for ./mypath/myfile
Dabei handelt .
es sich entweder um das Verzeichnis der Datei, in der sich das #include
befindet, und / oder um das aktuelle Arbeitsverzeichnis des Compilers und / oder um das Verzeichnisdefault_include_paths
und
<mypath/myfile> is short for <defaultincludepaths>/mypath/myfile
Wenn in ./
ist <default_include_paths>
, dann macht es keinen Unterschied.
Wenn mypath/myfile
es sich in einem anderen Include-Verzeichnis befindet, ist das Verhalten undefiniert.
#include "mypath/myfile"
ist nicht gleichbedeutend mit #include "./mypath/myfile"
. Wie in der Antwort von piCookie angegeben, weisen doppelte Anführungszeichen den Compiler an, auf implementierungsdefinierte Weise zu suchen - einschließlich der Suche an den angegebenen Stellen #include <...>
. (Eigentlich ist es wahrscheinlich gleichwertig, aber nur, weil zum Beispiel /usr/include/mypath/myfile
als /usr/include/./mypath/myfile
- zumindest auf Unix-ähnlichen Systemen bezeichnet werden kann.)
defaultincludepaths
, im Gegensatz zu einer anderen Bedeutung der Angabe .
(wie oben erwähnt). Dies hat die erwartete Konsequenz, dass beide #include "..."
und #include <...>
in dirpath
Das <file>
sind erzählt die Präprozessor in suchen -I
Verzeichnisse und in vordefinierte Verzeichnisse zuerst , dann in das Verzeichnis der C - Datei. Das "file"
Include weist den Präprozessor an, zuerst das Verzeichnis der Quelldatei zu durchsuchen und dann zu zurückzukehren-I
vordefinierte . Alle Ziele werden trotzdem gesucht, nur die Reihenfolge der Suche ist unterschiedlich.
Der Standard von 2011 behandelt hauptsächlich die Include-Dateien in "16.2 Aufnahme von Quelldateien".
2 Eine Vorverarbeitungsanweisung des Formulars
# include <h-char-sequence> new-line
Durchsucht eine Folge von implementierungsdefinierten Stellen nach einem Header, der durch die angegebene Reihenfolge zwischen den Trennzeichen <und> eindeutig identifiziert wird, und bewirkt, dass diese Anweisung durch den gesamten Inhalt des Headers ersetzt wird. Wie die Orte angegeben oder der Header identifiziert werden, ist implementierungsdefiniert.
3 Eine Vorverarbeitungsanweisung des Formulars
# include "q-char-sequence" new-line
bewirkt, dass diese Anweisung durch den gesamten Inhalt der Quelldatei ersetzt wird, der durch die angegebene Reihenfolge zwischen den Trennzeichen gekennzeichnet ist. Die benannte Quelldatei wird implementierungsdefiniert gesucht. Wenn diese Suche nicht unterstützt wird oder wenn die Suche fehlschlägt wird die Direktive so wiederaufbereitet, 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 Direktive.
Beachten Sie, dass "xxx"
sich das <xxx>
Formular zu einem Formular verschlechtert, wenn die Datei nicht gefunden wird. Der Rest ist implementierungsdefiniert.
-I
Geschäft angegeben ist?
-I
.
#include <file.h>
Weist den Compiler an, nach dem Header in seinem "Includes" -Verzeichnis zu suchen, z. B. nach MinGW, nach dem der Compiler file.h
in C: \ MinGW \ include \ suchen würde, oder wo immer Ihr Compiler installiert ist.
#include "file"
Weist den Compiler an, das aktuelle Verzeichnis (dh das Verzeichnis, in dem sich die Quelldatei befindet) zu durchsuchen file
.
Sie können das -I
Flag für GCC verwenden, um anzugeben, dass bei einem Einschluss mit spitzen Klammern auch nach Headern im Verzeichnis danach gesucht werden soll-I
. GCC behandelt das Verzeichnis nach dem Flag so, als wäre es das includes
Verzeichnis.
Wenn Sie beispielsweise eine Datei myheader.h
in Ihrem eigenen Verzeichnis haben, können Sie sagen#include <myheader.h>
ob Sie GCC mit dem Flag aufgerufen haben -I .
(was darauf hinweist, dass im aktuellen Verzeichnis nach Includes gesucht werden soll).
Ohne das -I
Flag müssen Sie #include "myheader.h"
die Datei einschließen oder myheader.h
in das include
Verzeichnis Ihres Compilers wechseln .
Standardmäßig - ja, sie sind unterschiedlich:
Eine Vorverarbeitungsanweisung des Formulars
#include <h-char-sequence> new-line
Durchsucht eine Folge von implementierungsdefinierten Stellen nach einem Header, der durch die angegebene Reihenfolge zwischen dem
<
und den>
Trennzeichen eindeutig identifiziert wird , und ersetzt diese Anweisung durch den gesamten Inhalt des Headers. Wie die Orte angegeben oder der Header identifiziert werden, ist implementierungsdefiniert.Eine Vorverarbeitungsanweisung des Formulars
#include "q-char-sequence" new-line
bewirkt, dass diese Anweisung durch den gesamten Inhalt der Quelldatei ersetzt wird, der durch die angegebene Reihenfolge zwischen den
"
Trennzeichen gekennzeichnet ist. Die benannte Quelldatei wird implementierungsdefiniert gesucht. Wenn diese Suche nicht unterstützt wird oder wenn die Suche fehlschlägt, wird die Anweisung erneut verarbeitet, als ob sie gelesen würde#include <h-char-sequence> new-line
mit der identischen enthaltenen Sequenz (einschließlich
>
Zeichen, falls vorhanden) aus der ursprünglichen Direktive.Eine Vorverarbeitungsanweisung des Formulars
#include pp-tokens new-line
(das nicht mit einem der beiden vorherigen Formulare übereinstimmt) ist zulässig. Die Vorverarbeitungstoken nach
include
der Direktive werden wie im normalen Text verarbeitet. (Jeder Bezeichner, der derzeit als Makroname definiert ist, wird durch seine Ersetzungsliste von Vorverarbeitungstoken ersetzt.) Die nach allen Ersetzungen resultierende Direktive muss mit einem der beiden vorherigen Formulare übereinstimmen. Die Methode, mit der eine Folge von Vorverarbeitungstoken zwischen einem<
und einem>
Vorverarbeitungstokenpaar oder einem"
Zeichenpaar zu einem Vorverarbeitungstoken mit einem einzelnen Headernamen kombiniert wird, ist implementierungsdefiniert.Definitionen:
h-char: Jedes Mitglied des Quellzeichensatzes mit Ausnahme des Zeilenumbruchs und
>
q-char: Jedes Mitglied des Quellzeichensatzes mit Ausnahme des Zeilenumbruchs und
"
Beachten Sie, dass der Standard keine Beziehung zwischen den implementierungsdefinierten Manieren feststellt. Das erste Formular sucht auf eine implementierungsdefinierte Weise und das andere auf eine (möglicherweise andere) implementierungsdefinierte Weise. Der Standard legt außerdem fest, dass bestimmte Include-Dateien vorhanden sein müssen (z. B. <stdio.h>
).
Formal müssten Sie das Handbuch für Ihren Compiler lesen, aber normalerweise #include "..."
durchsucht das Formular (traditionell) das Verzeichnis der Datei, in der das #include
zuerst gefunden wurde, und dann die Verzeichnisse, die das #include <...>
Formular durchsucht (den Include-Pfad, z. B. Systemheader) ).
Vielen Dank für die tollen Antworten, insb. Adam Stelmaszczyk und piCookie und aib.
Wie viele Programmierer habe ich die informelle Konvention verwendet, das "myApp.hpp"
Formular für anwendungsspezifische Dateien und das <libHeader.hpp>
Formular für Bibliotheks- und Compilersystemdateien zu verwenden, dh Dateien, die in /I
und angegeben sindINCLUDE
jahrelang Umgebungsvariable angegeben sind, und dachte, dies sei der Standard.
Der C-Standard besagt jedoch, dass die Suchreihenfolge implementierungsspezifisch ist, was die Portabilität erschweren kann. Um die Sache noch schlimmer zu machen, verwenden wir Jam, der automatisch herausfindet, wo sich die Include-Dateien befinden. Sie können relative oder absolute Pfade für Ihre Include-Dateien verwenden. dh
#include "../../MyProgDir/SourceDir1/someFile.hpp"
Ältere Versionen von MSVS erforderten doppelte Backslashes (\\), aber das ist jetzt nicht erforderlich. Ich weiß nicht, wann es sich geändert hat. Verwenden Sie einfach Schrägstriche, um die Kompatibilität mit 'nix zu gewährleisten (Windows akzeptiert dies).
Wenn Sie sich darüber wirklich Sorgen machen, verwenden Sie"./myHeader.h"
für eine Include-Datei im selben Verzeichnis wie der Quellcode (in meinem aktuellen, sehr großen Projekt sind einige doppelte Include-Dateinamen verstreut - wirklich ein Problem bei der Konfigurationsverwaltung).
Hier ist die MSDN-Erklärung, die hier zur Vereinfachung kopiert wurde.
Zitierte Form
Der Präprozessor sucht nach Include-Dateien in dieser Reihenfolge:
- Im selben Verzeichnis wie die Datei, die die Anweisung #include enthält.
- In den Verzeichnissen der aktuell geöffneten Include-Dateien in umgekehrter Reihenfolge, in der
sie geöffnet wurden. Die Suche beginnt im Verzeichnis der übergeordneten Include-Datei und wird
in den Verzeichnissen aller Großeltern-Include-Dateien nach oben fortgesetzt.- Entlang des Pfades, der von jeder
/I
Compileroption angegeben wird .- Entlang der Pfade, die von der
INCLUDE
Umgebungsvariablen angegeben werden.Winkelklammerform
Der Präprozessor sucht nach Include-Dateien in dieser Reihenfolge:
- Entlang des von jedem angegebenen Pfades
/I
Compileroption .- Wenn die Kompilierung in der Befehlszeile erfolgt, entlang der Pfade, die von der
INCLUDE
Umgebungsvariablen angegeben werden.
Zumindest für die GCC-Version <= 3.0 generiert die spitze Klammerform keine Abhängigkeit zwischen der enthaltenen und der eingeschlossenen Datei.
Wenn Sie also Abhängigkeitsregeln generieren möchten (z. B. mit der Option GCC -M), müssen Sie das Anführungszeichen für die Dateien verwenden, die in den Abhängigkeitsbaum aufgenommen werden sollen.
Für #include ""
einen Compiler sucht normalerweise den Ordner der Datei , die das beinhalten enthält und dann die anderen Ordner. Denn #include <>
der Compiler durchsucht nicht den Ordner der aktuellen Datei.
<filename>
und "filename"
sucht nach implementierungsdefinierten Stellen.
Wenn Sie #include <Dateiname> verwenden, sucht der Vorprozessor nach der Datei im Verzeichnis der C \ C ++ - Headerdateien (stdio.h \ cstdio, Zeichenfolge, Vektor usw.). Wenn Sie jedoch #include "Dateiname" verwenden: Zuerst sucht der Vorprozessor nach der Datei im aktuellen Verzeichnis, und wenn dies nicht der Fall ist, sucht er sie im Verzeichnis der C \ C ++ - Headerdateien.
#include
bezieht sich die Richtlinie überhaupt nicht ausschließlich auf Dateien.
Ein #include mit spitzen Klammern durchsucht eine "implementierungsabhängige Liste von Stellen" (was eine sehr komplizierte Art ist, "Systemheader" zu sagen) nach der einzuschließenden Datei.
Ein #include mit Anführungszeichen sucht nur nach einer Datei (und "in implementierungsabhängiger Weise" bleh). Das heißt, im normalen Englisch wird versucht, den Pfad / Dateinamen anzuwenden, den Sie darauf werfen, und es wird kein Systempfad vorangestellt oder anderweitig manipuliert.
Wenn #include "" fehlschlägt, wird es vom Standard erneut als #include <> gelesen.
Die gcc-Dokumentation enthält eine (compilerspezifische) Beschreibung, die zwar spezifisch für gcc und nicht für den Standard ist, aber viel einfacher zu verstehen ist als die anwaltliche Rede über die ISO-Standards.
zlib.h
in meinen 'Benutzer'-Suchpfaden eine andere Version im Systemsuchpfad. Enthält dann #include <zlib.h>
die Systemversion und #include "zlib.h"
meine eigene?
#include "filename" // User defined header
#include <filename> // Standard library header.
Beispiel:
Der Dateiname hier ist 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
In der Klassenimplementierung (z. B. Seller.cpp
und in anderen Dateien, die die Datei verwenden Seller.h
) sollte der vom Benutzer definierte Header nun wie folgt enthalten sein:
#include "Seller.h"
#include <>
ist für vordefinierte Header-DateienWenn die Header-Datei vordefiniert ist, schreiben Sie einfach den Namen der Header-Datei in eckige Klammern und es sieht folgendermaßen aus (vorausgesetzt, wir haben einen vordefinierten Header-Dateinamen iostream):
#include <iostream>
#include " "
ist für Header-Dateien, die der Programmierer definiertWenn Sie (der Programmierer) Ihre eigene Header-Datei geschrieben haben, würden Sie den Namen der Header-Datei in Anführungszeichen schreiben. Angenommen, Sie haben eine Header-Datei mit dem Namen geschrieben myfile.h
. Dies ist ein Beispiel dafür, wie Sie die include-Direktive verwenden würden, um diese Datei einzuschließen:
#include "myfile.h"
Viele der Antworten hier konzentrieren sich auf die Pfade, die der Compiler durchsucht, um die Datei zu finden. Während dies bei den meisten Compilern der Fall ist, darf ein konformer Compiler mit den Auswirkungen der Standardheader vorprogrammiert werden und #include <list>
beispielsweise als Schalter behandelt werden, und er muss überhaupt nicht als Datei vorhanden sein.
Dies ist nicht rein hypothetisch. Es gibt mindestens einen Compiler, der so funktioniert. Die Verwendung #include <xxx>
nur mit Standard-Headern wird empfohlen.
#include <abc.h>
wird verwendet, um Standardbibliotheksdateien einzuschließen. Der Compiler überprüft also die Speicherorte, an denen sich Standardbibliotheksheader befinden.
#include "xyz.h"
weist den Compiler an, benutzerdefinierte Header-Dateien einzuschließen. Der Compiler sucht also im aktuellen Ordner oder in den -I
definierten Ordnern nach diesen Header-Dateien .
Fügen Sie in C ++ eine Datei auf zwei Arten hinzu:
Das erste ist #include, das den Präprozessor anweist, nach der Datei am vordefinierten Standardspeicherort zu suchen. Dieser Speicherort ist häufig eine INCLUDE-Umgebungsvariable, die den Pfad zum Einschließen von Dateien angibt.
Der zweite Typ ist #include "Dateiname", der den Präprozessor anweist, zuerst nach der Datei im aktuellen Verzeichnis und dann an den vordefinierten Speicherorten zu suchen, die der Benutzer eingerichtet hat.
Sucht zunächst nach dem Vorhandensein einer Header-Datei im aktuellen Verzeichnis, von dem aus die Direktive aufgerufen wird. Wird es nicht gefunden, wird in der vorkonfigurierten Liste der Standardsystemverzeichnisse gesucht.
Dies sucht nach dem Vorhandensein einer Header-Datei im aktuellen Verzeichnis, von dem aus die Direktive aufgerufen wird.
Die genaue Liste der Suchverzeichnisse hängt vom Zielsystem ab, davon, wie GCC konfiguriert ist und wo es installiert ist. Sie finden die Suchverzeichnisliste Ihres GCC-Compilers, indem Sie sie mit der Option -v ausführen.
Sie können dem Suchpfad zusätzliche Verzeichnisse hinzufügen, indem Sie - I dir verwenden . Dadurch wird dir nach dem aktuellen Verzeichnis (für die Anführungszeichenform der Direktive) und vor den Standardsystemverzeichnissen durchsucht.
Grundsätzlich ist die Form "xxx" nichts anderes als die Suche im aktuellen Verzeichnis; Wenn nicht gefunden, fällt das Formular zurück
#include "header.h"
Formulars ist nicht korrekt, @personal_cloud. Ich halte die Antwort von piCookie und Yann Droneaud für am relevantesten, da sie identifizieren, woher ihre Informationen stammen. Ich finde die am besten gewählte Antwort auch nicht ganz zufriedenstellend.
Das #include <filename>
wird verwendet, wenn auf eine Systemdatei verwiesen wird. Dies ist eine Header-Datei, die sich an Standardspeicherorten des Systems wie /usr/include
oder befindet /usr/local/include
. Für Ihre eigenen Dateien, die in einem anderen Programm enthalten sein müssen, müssen Sie die #include "filename"
Syntax verwenden.
Der "<Dateiname>" sucht in Standardspeicherorten der C-Bibliothek
Während "Dateiname" auch im aktuellen Verzeichnis sucht.
Idealerweise verwenden Sie <...> für Standard-C-Bibliotheken und "..." für Bibliotheken, die Sie schreiben und die im aktuellen Verzeichnis vorhanden sind.
Die einfache allgemeine Regel besteht darin, spitze Klammern zu verwenden, um Header-Dateien einzuschließen, die mit dem Compiler geliefert werden. Verwenden Sie doppelte Anführungszeichen, um andere Header-Dateien einzuschließen. Die meisten Compiler machen das so.
1.9 - Header-Dateien erläutern ausführlicher die Anweisungen vor dem Prozessor. Wenn Sie ein Anfänger sind, sollte diese Seite Ihnen helfen, all das zu verstehen. Ich habe es von hier gelernt und habe es bei der Arbeit verfolgt.
#include <filename>
wird verwendet, wenn Sie die Header-Datei des C / C ++ - Systems oder der Compiler-Bibliotheken verwenden möchten. Diese Bibliotheken können stdio.h, string.h, math.h usw. sein.
#include "path-to-file/filename"
wird verwendet, wenn Sie Ihre eigene benutzerdefinierte Header-Datei verwenden möchten, die sich in Ihrem Projektordner oder an einer anderen Stelle befindet.
Weitere Informationen zu Präprozessoren und Headern. Lesen Sie C - Präprozessoren .
#include <filename>
#include "filename"
#include <filename>
und durchsucht die Header-Datei dort, wo die System-Header-Dateien gespeichert sind.#include <filename>
.Um die Suchreihenfolge auf Ihrem System mit gcc basierend auf der aktuellen Konfiguration anzuzeigen, können Sie den folgenden Befehl ausführen. Weitere Details zu diesem Befehl finden Sie hier
cpp -v /dev/null -o /dev/null
Apple LLVM Version 10.0.0 (clang-1000.10.44.2)
Ziel: x86_64-apple-darwin18.0.0
Thread-Modell: posix InstalledDir: Library / Developer / CommandLineTools / usr / bin
"/ Library / Developer / CommandLineTools / usr / bin / clang" -cc1 -triple x86_64-apple-macosx10.14.0 -Wdeprecated-objc-isa-usage -Werror = veraltet-objc-isa-usage -E -disable-free - disable-llvm-verifier -discard-value-names -main-file-name 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-erweiterte-Block-Signatur -fobjc-Laufzeit = macosx-10.14.0 -fmax-type-align = 16 -fdiagnostics-show-option -fcolor-diagnostics -traditional-cpp -o - -xc / dev / null
clang -cc1 Version 10.0.0 (clang-1000.10.44.2) Standardziel x86_64-apple-darwin18.0.0 ignoriert nicht vorhandenes Verzeichnis "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/local/include" ignoriert nicht vorhandenes Verzeichnis "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/Library/Frameworks"
#include "..." Die Suche beginnt hier:
#include <...> Die Suche beginnt hier:
/ usr / local / include
/ Bibliothek / Entwickler / CommandLineTools / usr / lib / clang / 10.0.0 / include
/ Bibliothek / Entwickler / CommandLineTools / usr / include
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include
/ Library / Developer / CommandLineTools / SDKs / MacOSX10.14.sdk / System / Library / Frameworks (Framework-Verzeichnis)
Ende der Suchliste.
Es gibt zwei Möglichkeiten, eine # include-Anweisung zu schreiben. Dies sind:
#include"filename"
#include<filename>
Die Bedeutung jeder Form ist
#include"mylib.h"
Dieser Befehl sucht nach der Datei mylib.h
im aktuellen Verzeichnis sowie nach der angegebenen Liste von Verzeichnissen, wie im Include-Suchpfad angegeben, der möglicherweise eingerichtet wurde.
#include<mylib.h>
Dieser Befehl sucht mylib.h
nur in der angegebenen Liste von Verzeichnissen nach der Datei .
Der Include-Suchpfad ist nichts anderes als eine Liste von Verzeichnissen, die nach der enthaltenen Datei durchsucht werden sollen. Mit verschiedenen C-Compilern können Sie den Suchpfad auf verschiedene Arten festlegen.