Dans les langages de programmation C et C ++, quelle est la différence entre l'utilisation de crochets angulaires et l'utilisation de guillemets dans une include
instruction, comme suit?
#include <filename>
#include "filename"
c++
c
include
header-files
c-preprocessor
quête49
la source
la source
Réponses:
En pratique, la différence réside dans l'emplacement où le préprocesseur recherche le fichier inclus.
Pour
#include <filename>
le préprocesseur recherche de manière dépendante de l'implémentation, normalement dans des répertoires de recherche pré-désignés par le compilateur / IDE. Cette méthode est normalement utilisée pour inclure des fichiers d'en-tête de bibliothèque standard.Car
#include "filename"
le préprocesseur recherche d'abord dans le même répertoire que le fichier contenant la directive, puis suit le chemin de recherche utilisé pour le#include <filename>
formulaire. Cette méthode est normalement utilisée pour inclure des fichiers d'en-tête définis par le programmeur.Une description plus complète est disponible dans la documentation GCC sur les chemins de recherche .
la source
#include <...>
utilisé le package installé sur le système et#include "..."
utilisé la version du référentiel à proximité. Je pourrais les avoir à l'envers. Dans les deux cas, le garde d'inclusion dans l'en-tête empaqueté est préfixé par un trait de soulignement. (Cela pourrait être une convention pour les packages ou peut-être un moyen d'empêcher délibérément de mélanger les deux, bien que les qualificatifs de version auraient plus de sens pour moi.)La seule façon de le savoir est de lire la documentation de votre implémentation.
Dans la norme C , section 6.10.2, les paragraphes 2 à 4 stipulent:
la source
La séquence de caractères entre <et> fait uniquement référence à un en-tête, qui n'est pas nécessairement un fichier. Les implémentations sont à peu près libres d'utiliser la séquence de caractères comme elles le souhaitent. (Généralement, cependant, il suffit de le traiter comme un nom de fichier et de faire une recherche dans le chemin d'inclusion , comme l'indiquent les autres articles.)
Si le
#include "file"
formulaire est utilisé, l'implémentation recherche d'abord un fichier du nom donné, s'il est pris en charge. Sinon (pris en charge) ou si la recherche échoue, l'implémentation se comporte comme si l'autre#include <file>
formulaire ( ) était utilisé.En outre, un troisième formulaire existe et est utilisé lorsque la
#include
directive ne correspond à aucun des formulaires ci-dessus. Sous cette forme, un prétraitement de base (tel qu'une expansion de macro) est effectué sur les "opérandes" de la#include
directive, et le résultat devrait correspondre à l'une des deux autres formes.la source
<
et>
comme clé pour indexer dans la bibliothèque.Quelques bonnes réponses font ici référence au standard C mais ont oublié le standard POSIX, en particulier le comportement spécifique de la commande c99 (par exemple le compilateur C) .
Selon The Open Group Base Specifications Issue 7 ,
Donc, dans un environnement compatible POSIX, avec un compilateur C compatible POSIX,
#include "file.h"
va probablement chercher en./file.h
premier, où.
est le répertoire où se trouve le fichier avec l'#include
instruction, tandis que#include <file.h>
, va probablement chercher en/usr/include/file.h
premier, où/usr/include
est votre système défini emplacements habituels pour les en-têtes (il ne semble pas défini par POSIX).la source
c99
- qui est le nom POSIX du compilateur C. (La norme POSIX 2008 pouvait difficilement faire référence à C11; la mise à jour 2013 de POSIX 2008 n'a pas changé la norme C à laquelle elle faisait référence.)-L
.La documentation de GCC indique ce qui suit sur la différence entre les deux:
la source
Cela fait:
avec
.
soit le répertoire du fichier où le#include
est contenu, et / ou le répertoire de travail actuel du compilateur, et / oudefault_include_paths
et
Si
./
c'est le cas<default_include_paths>
, cela ne fait aucune différence.Si se
mypath/myfile
trouve dans un autre répertoire d'inclusion, le comportement n'est pas défini.la source
#include "mypath/myfile"
n'est pas équivalent à#include "./mypath/myfile"
. Comme le dit la réponse de piCookie, les guillemets doubles indiquent au compilateur de rechercher d'une manière définie par l'implémentation - ce qui inclut la recherche aux endroits spécifiés#include <...>
. (En fait, c'est probablement équivalent, mais seulement parce que, par exemple,/usr/include/mypath/myfile
on peut l'appeler/usr/include/./mypath/myfile
- au moins sur les systèmes de type Unix.)defaultincludepaths
, au lieu de donner une autre signification au.
(comme mentionné ci-dessus). Cela a la conséquence attendue que les deux#include "..."
et la#include <...>
recherche dans dirpathL'
<file>
inclure indique le préprocesseur de rechercher dans les-I
répertoires et dans des répertoires prédéfinis d' abord , puis dans le répertoire du fichier .c. L'"file"
inclure indique le préprocesseur pour rechercher le répertoire du fichier source première , puis revenir à-I
et prédéfini. Toutes les destinations sont recherchées de toute façon, seul l'ordre de recherche est différent.La norme 2011 traite principalement des fichiers inclus dans "16.2 Inclusion de fichiers source".
Notez que le
"xxx"
formulaire se dégrade en<xxx>
formulaire si le fichier est introuvable. Le reste est défini par l'implémentation.la source
-I
activité est spécifiée?-I
.#include <file.h>
indique au compilateur de rechercher l'en-tête dans son répertoire "includes", par exemple pour MinGW, le compilateur rechercheraitfile.h
dans C: \ MinGW \ include \ ou partout où votre compilateur est installé.#include "file"
indique au compilateur de rechercher le répertoire courant (c'est-à-dire le répertoire dans lequel réside le fichier source)file
.Vous pouvez utiliser l'
-I
indicateur pour GCC pour lui indiquer que, lorsqu'il rencontre une inclusion avec des crochets angulaires, il doit également rechercher les en-têtes dans le répertoire après-I
. GCC traitera le répertoire après l'indicateur comme s'il s'agissait duincludes
répertoire.Par exemple, si vous avez un fichier appelé
myheader.h
dans votre propre répertoire, vous pouvez dire#include <myheader.h>
si vous avez appelé GCC avec l'indicateur-I .
(indiquant qu'il doit rechercher les inclusions dans le répertoire actuel.)Sans l'
-I
indicateur, vous devrez utiliser#include "myheader.h"
pour inclure le fichier ou vous déplacermyheader.h
vers leinclude
répertoire de votre compilateur.la source
Selon la norme - oui, ils sont différents:
Notez que la norme ne dit aucune relation entre les manières définies par l'implémentation. Le premier formulaire recherche d'une manière définie par l'implémentation, et l'autre d'une manière (éventuellement autre) définie par l'implémentation. La norme spécifie également que certains fichiers include doivent être présents (par exemple,
<stdio.h>
).Formellement, vous devrez lire le manuel de votre compilateur, mais normalement (par tradition) le
#include "..."
formulaire recherche le répertoire du fichier dans lequel le a#include
été trouvé en premier, puis les répertoires que le#include <...>
formulaire recherche (le chemin d'inclusion, par exemple les en-têtes du système) ).la source
Merci pour les bonnes réponses, esp. Adam Stelmaszczyk et piCookie, et aib.
Comme de nombreux programmeurs, j'ai utilisé la convention informelle d'utiliser le
"myApp.hpp"
formulaire pour les fichiers spécifiques à l'application et le<libHeader.hpp>
formulaire pour les fichiers système de bibliothèque et de compilateur, c'est-à-dire les fichiers spécifiés dans/I
et laINCLUDE
variable d'environnement, pendant des années en pensant que c'était la norme.Cependant, la norme C indique que l'ordre de recherche est spécifique à l'implémentation, ce qui peut compliquer la portabilité. Pour aggraver les choses, nous utilisons la confiture, qui détermine automatiquement où se trouvent les fichiers d'inclusion. Vous pouvez utiliser des chemins relatifs ou absolus pour vos fichiers d'inclusion. c'est à dire
Les anciennes versions de MSVS nécessitaient des doubles barres obliques inverses (\\), mais maintenant ce n'est plus nécessaire. Je ne sais pas quand ça a changé. Utilisez simplement des barres obliques pour la compatibilité avec 'nix (Windows l'acceptera).
Si vous êtes vraiment inquiet à ce sujet, utilisez
"./myHeader.h"
un fichier include dans le même répertoire que le code source (mon projet actuel très volumineux a des noms de fichiers include en double dispersés - vraiment un problème de gestion de la configuration).Voici l' explication MSDN copiée ici pour votre commodité).
la source
Au moins pour la version GCC <= 3.0, la forme équerre ne génère pas de dépendance entre le fichier inclus et le fichier inclus.
Donc si vous voulez générer des règles de dépendance (en utilisant l'option GCC -M par exemple), vous devez utiliser le formulaire entre guillemets pour les fichiers qui doivent être inclus dans l'arbre de dépendance.
(Voir http://gcc.gnu.org/onlinedocs/cpp/Invocation.html )
la source
Un
#include ""
compilateur recherche normalement le dossier du fichier qui contient cette inclusion, puis les autres dossiers. Pour#include <>
le compilateur ne recherche pas le dossier du fichier actuel.la source
<filename>
et"filename"
recherche des endroits définis par l'implémentation.Lorsque vous utilisez #include <nomfichier>, le préprocesseur recherche le fichier dans le répertoire des fichiers d'en-tête C \ C ++ (stdio.h \ cstdio, chaîne, vecteur, etc.). Mais, lorsque vous utilisez #include "filename": d'abord, le préprocesseur recherche le fichier dans le répertoire courant, et s'il ne le fait pas ici - il le recherche dans le répertoire des fichiers d'en-tête C \ C ++.
la source
#include
directive n'est pas du tout strictement liée aux fichiers.Un #include avec des crochets cherchera une "liste d'emplacements dépendants de l'implémentation" (ce qui est une manière très compliquée de dire "en-têtes système") pour le fichier à inclure.
Un #include avec des guillemets cherchera simplement un fichier (et, "d'une manière dépendante de l'implémentation", bleh). Ce qui signifie qu'en anglais normal, il essaiera d'appliquer le chemin / nom de fichier que vous lui lancez et ne ajoutera pas de chemin système ou ne le modifiera pas autrement.
De plus, si #include "" échoue, il est relu comme #include <> par la norme.
La documentation de gcc a une description (spécifique au compilateur) qui, bien qu'elle soit spécifique à gcc et non à la norme, est beaucoup plus facile à comprendre que le discours de style avocat des normes ISO.
la source
zlib.h
dans mes chemins de recherche "utilisateur", et qu'une version différente existe dans le chemin de recherche du système, alors#include <zlib.h>
inclut la version du système et#include "zlib.h"
la mienne?Exemple:
Le nom de fichier ici est
Seller.h
:Dans l'implémentation de classe (par exemple,
Seller.cpp
et dans d'autres fichiers qui utiliseront le fichierSeller.h
), l'en-tête défini par l'utilisateur doit maintenant être inclus, comme suit:la source
#include <>
est pour les fichiers d'en-tête prédéfinisSi le fichier d'en-tête est prédéfini, vous écririez simplement le nom du fichier d'en-tête entre crochets angulaires, et cela ressemblerait à ceci (en supposant que nous avons un nom de fichier d'en-tête prédéfini iostream):
#include " "
est pour les fichiers d'en-tête que le programmeur définitSi vous (le programmeur) avez écrit votre propre fichier d'en-tête, vous écririez le nom du fichier d'en-tête entre guillemets. Supposons donc que vous ayez écrit un fichier d'en-tête appelé
myfile.h
, alors voici un exemple de la façon dont vous utiliseriez la directive include pour inclure ce fichier:la source
De nombreuses réponses se concentrent ici sur les chemins que le compilateur recherchera afin de trouver le fichier. Bien que ce soit ce que font la plupart des compilateurs, un compilateur conforme est autorisé à être préprogrammé avec les effets des en-têtes standard, et à le traiter, par exemple,
#include <list>
comme un commutateur, et il n'a pas besoin d'exister en tant que fichier.Ce n'est pas purement hypothétique. Il existe au moins un compilateur qui fonctionne de cette façon. L'utilisation
#include <xxx>
uniquement avec des en-têtes standard est recommandée.la source
est utilisé pour inclure des fichiers de bibliothèque standard. Ainsi, le compilateur vérifiera les emplacements où résident les en-têtes de bibliothèque standard.
indiquera au compilateur d'inclure les fichiers d'en-tête définis par l'utilisateur. Ainsi, le compilateur vérifiera ces fichiers d'en-tête dans le dossier actuel ou les
-I
dossiers définis.la source
En C ++, incluez un fichier de deux manières:
Le premier est #include qui indique au préprocesseur de rechercher le fichier à l'emplacement par défaut prédéfini. Cet emplacement est souvent une variable d'environnement INCLUDE qui indique le chemin d'accès pour inclure les fichiers.
Et le deuxième type est #include "filename" qui indique au préprocesseur de rechercher d'abord le fichier dans le répertoire courant, puis de le rechercher dans les emplacements prédéfinis que l'utilisateur a configurés.
la source
Formulaire 1 - #inclut <xxx>
Tout d'abord, recherche la présence du fichier d'en-tête dans le répertoire courant à partir duquel la directive est invoquée. S'il n'est pas trouvé, il recherche dans la liste préconfigurée des répertoires système standard.
Formulaire 2 - # inclure "xxx"
Cela recherche la présence du fichier d'en-tête dans le répertoire courant d'où la directive est invoquée.
La liste exacte des répertoires de recherche dépend du système cible, de la configuration de GCC et de l'endroit où il est installé. Vous pouvez trouver la liste des répertoires de recherche de votre compilateur GCC en l'exécutant avec l'option -v.
Vous pouvez ajouter des répertoires supplémentaires au chemin de recherche en utilisant - I dir , ce qui entraîne la recherche de dir après le répertoire en cours (pour le formulaire de citation de la directive) et avant les répertoires système standard.
Fondamentalement, le formulaire "xxx" n'est rien d'autre qu'une recherche dans le répertoire courant; sinon trouvé retomber le formulaire
la source
#include "header.h"
formulaire n'est pas exacte, @personal_cloud. Je considère que la réponse de piCookie et Yann Droneaud est la plus pertinente car ils identifient la provenance de leurs informations. Je ne trouve pas non plus la réponse la plus votée entièrement satisfaisante.Le
#include <filename>
est utilisé lorsqu'un fichier système est référencé. Il s'agit d'un fichier d'en-tête qui peut être trouvé aux emplacements par défaut du système comme/usr/include
ou/usr/local/include
. Pour vos propres fichiers qui doivent être inclus dans un autre programme, vous devez utiliser la#include "filename"
syntaxe.la source
Idéalement, vous utiliseriez <...> pour les bibliothèques C standard et "..." pour les bibliothèques que vous écrivez et qui sont présentes dans le répertoire courant.
la source
La règle générale simple consiste à utiliser des crochets inclinés pour inclure les fichiers d'en-tête fournis avec le compilateur. Utilisez des guillemets doubles pour inclure tout autre fichier d'en-tête. La plupart des compilateurs le font de cette façon.
1.9 - Les fichiers d'en-tête expliquent plus en détail les directives de pré-processeur. Si vous êtes un programmeur débutant, cette page devrait vous aider à comprendre tout cela. Je l'ai appris d'ici et je l'ai suivi au travail.
la source
#include <filename>
est utilisé lorsque vous souhaitez utiliser le fichier d'en-tête du système C / C ++ ou des bibliothèques du compilateur. Ces bibliothèques peuvent être stdio.h, string.h, math.h, etc.
#include "path-to-file/filename"
est utilisé lorsque vous souhaitez utiliser votre propre fichier d'en-tête personnalisé qui se trouve dans votre dossier de projet ou ailleurs.
Pour plus d'informations sur les préprocesseurs et l'en-tête. Lisez C - Préprocesseurs .
la source
#include <filename>
#include "filename"
#include <filename>
et recherche ce fichier d'en-tête à l'endroit où les fichiers d'en-tête du système sont stockés.#include <filename>
.la source
Pour voir l'ordre de recherche sur votre système à l'aide de gcc, en fonction de la configuration actuelle, vous pouvez exécuter la commande suivante. Vous pouvez trouver plus de détails sur cette commande ici
cpp -v /dev/null -o /dev/null
la source
Inclut un fichier où se trouve le répertoire d'inclusion par défaut.
Inclut un fichier dans le répertoire courant dans lequel il a été compilé.
la source
Il existe deux façons d'écrire une instruction #include, à savoir:
La signification de chaque forme est
Cette commande rechercherait le fichier
mylib.h
dans le répertoire courant ainsi que la liste de répertoires spécifiée comme mentionné dans le chemin de recherche d'inclusion qui aurait pu être configuré.Cette commande rechercherait le fichier
mylib.h
dans la liste de répertoires spécifiée uniquement.Le chemin de recherche inclus n'est rien d'autre qu'une liste de répertoires qui seraient recherchés pour le fichier inclus. Différents compilateurs C vous permettent de définir le chemin de recherche de différentes manières.
la source