Question Quelle est la différence entre #include et #include "filename"?


Dans les langages de programmation C et C ++, quelle est la différence entre l'utilisation de chevrons et l'utilisation de guillemets dans un include déclaration, comme suit?

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

1809
2017-08-22 01:40


origine


Réponses:


En pratique, la différence se situe à 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 les 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.

Pour #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> forme. 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 le GCC documentation sur les chemins de recherche.


1045
2017-08-22 01:40



La seule façon de savoir est de lire la documentation de votre implémentation.

Dans la norme C, section 6.10.2, les paragraphes 2 à 4 indiquent:

  • Une directive de pré-traitement du formulaire

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

    recherche une séquence d'emplacements définis par l'implémentation pour un en-tête identifié uniquement par la séquence spécifiée entre < et > délimiteurs, et provoque le remplacement de cette directive par tout le contenu de l'en-tête. La façon dont les lieux sont spécifiés ou l'en-tête identifié est défini par l'implémentation.

  • Une directive de pré-traitement du formulaire

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

    provoque le remplacement de cette directive par tout le contenu du fichier source identifié par la séquence spécifiée entre le " délimiteurs. Le fichier source nommé est recherché d'une manière définie par l'implémentation. Si cette recherche n'est pas prise en charge ou si la recherche échoue, la directive est retraitée comme si elle était lue

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

    avec la séquence contenue identique (y compris > caractères, le cas échéant) de l'original   directif.

  • Une directive de pré-traitement du formulaire

    #include pp-tokens new-line
    

    (qui ne correspond pas à l'une des deux formes précédentes) est autorisé. Les jetons de prétraitement après include dans la directive sont traitées comme dans un texte normal. (Chaque identifiant actuellement défini en tant que nom de macro est remplacé par sa liste de remplacement de jetons de prétraitement.) La directive résultant de tous les remplacements doit correspondre à l'un des deux formulaires précédents. La méthode par laquelle une séquence de jetons de prétraitement entre un < et un > paire de jetons de prétraitement ou une paire de " Les caractères sont combinés en un seul nom d'en-tête. Le jeton de prétraitement est défini par l'implémentation.

Définitions

  • h-char: tout membre du jeu de caractères source sauf le caractère de nouvelle ligne et >

  • q-char: tout membre du jeu de caractères source sauf le caractère de nouvelle ligne et "


594
2017-09-16 21:06



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 pratiquement libres d'utiliser la séquence de caractères comme ils le souhaitent. (Surtout, il suffit de le traiter comme un nom de fichier et faire une recherche dans le inclure le chemin, comme les autres messages l'état.)

Si la #include "file" formulaire est utilisé, l'implémentation recherche d'abord un fichier du nom donné, s'il est pris en charge. Sinon (supporté), ou si la recherche échoue, l'implémentation se comporte comme si l'autre (#include <file>) a été utilisé.

En outre, une troisième forme existe et est utilisée lorsque le #include La directive ne correspond à aucun des formulaires ci-dessus. Sous cette forme, un pré-traitement de base (tel que la macro-expansion) est effectué sur les "opérandes" du #include directive, et le résultat devrait correspondre à l'un des deux autres formulaires.


214
2017-09-08 17:43



Quelques bonnes réponses ici font référence au standard C mais oublient le standard POSIX, en particulier le comportement spécifique du c99 (par exemple, compilateur C) commander.

Selon Les spécifications de base de groupe ouvert, numéro 7,

-JE  annuaire

Changer l'algorithme de recherche des en-têtes dont les noms ne sont pas des chemins absolus à chercher dans le répertoire nommé par le annuaire pathname avant de regarder dans les endroits habituels. Ainsi, les en-têtes dont les noms sont entre guillemets ("") doivent d'abord être recherchés dans le répertoire du fichier #comprendre ligne, puis dans les répertoires nommés dans -JE options, et durent dans les endroits habituels. Pour les en-têtes dont les noms sont entre crochets ("<>"), l'en-tête ne doit être recherché que dans les répertoires nommés dans -JE options, puis dans les lieux habituels. Répertoires nommés dans -JE les options doivent être recherchées dans l'ordre spécifié. Les implémentations doivent prendre en charge au moins dix instances de cette option dans un seul c99 invocation de commande.

Ainsi, dans un environnement compatible POSIX, avec un compilateur C compatible POSIX, #include "file.h" va probablement chercher ./file.h d'abord, où . est le répertoire où est le fichier avec le #include déclaration, tandis que #include <file.h>, va probablement chercher /usr/include/file.h d'abord, où /usr/include Votre système est-il défini lieux habituels pour les en-têtes (il ne semble pas défini par POSIX).


92
2017-07-20 09:29



Cela fait:

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

avec . étant soit le répertoire du fichier où le #include est contenu dans, et / ou le répertoire de travail courant du compilateur, et / ou default_include_paths

et

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

Si ./ est dans <default_include_paths>alors ça ne fait pas de différence.

Si mypath/myfile est dans un autre répertoire include, le comportement est indéfini.


36
2018-02-08 11:45



La documentation du GCC indique ce qui suit à propos de la différence entre les deux:

Les fichiers d'en-tête utilisateur et système sont inclus à l'aide de la directive de prétraitement ‘#include’. Il a deux variantes:

#include <file>

Cette variante est utilisée pour les fichiers d'en-tête système. Il recherche un fichier nommé fichier dans une liste standard de répertoires système. Vous pouvez ajouter des répertoires à cette liste avec le -I option (voir Invocation).

#include "file"

Cette variante est utilisée pour les fichiers d'en-tête de votre propre programme. Il recherche d'abord un fichier nommé fichier dans le répertoire contenant le fichier en cours, puis dans les répertoires quote, puis les mêmes répertoires utilisés pour <file>. Vous pouvez ajouter des répertoires à la liste des répertoires de devis avec le -iquote option.     L'argument de ‘#include’, qu'il soit délimité par des guillemets ou des chevrons, se comporte comme une constante de chaîne dans la mesure où les commentaires ne sont pas reconnus et les noms de macros ne sont pas développés. Ainsi, #include <x/*y> spécifie l'inclusion d'un fichier d'en-tête système nommé x/*y.

Toutefois, si des barres obliques inverses se produisent dans le fichier, elles sont considérées comme des caractères de texte ordinaires et non comme des caractères d'échappement. Aucune des séquences d'échappement de caractères appropriées aux constantes de chaîne dans C n'est traitée. Ainsi,#include "x\n\\y"spécifie un nom de fichier contenant trois barres obliques inverses. (Certains systèmes interprètent '\' comme un séparateur de chemin d'accès. ‘/’ de la même façon. Il est le plus portable à utiliser seulement ‘/’.)

C'est une erreur s'il y a quelque chose (autre que des commentaires) sur la ligne après le nom du fichier.


30
2018-01-14 04:52



le <file> include indique au préprocesseur de rechercher dans -I répertoires et dans des répertoires prédéfinis premier, puis dans le répertoire du fichier .c. le "file" include indique au préprocesseur de rechercher dans le répertoire du fichier source premier, 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 de 2011 traite principalement des fichiers d'inclusion dans «16.2 Inclusion du fichier source».

2 Une directive de pré-traitement du formulaire

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

recherche dans une séquence d'emplacements définis par l'implémentation un en-tête identifié uniquement par le   séquence spécifiée entre les délimiteurs <et>, et provoque la   remplacement de cette directive par tout le contenu de l'en-tête.   Comment les lieux sont spécifiés ou l'en-tête identifié est   implémenté-défini.

3 Une directive de pré-traitement du formulaire

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

provoque le remplacement de cette directive par l'intégralité du contenu du fichier source identifié par le   séquence spécifiée entre les "délimiteurs".   recherché d'une manière définie par l'implémentation. Si cette recherche est   n'est pas prise en charge ou si la recherche échoue, la directive est retraitée   si c'est lu

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

avec la séquence contenue identique (y compris> les caractères, le cas échéant) de la directive d'origine.

Notez que "xxx" forme se dégrade en <xxx> forme si le fichier est introuvable. Le reste est défini par l'implémentation.


23
2017-09-03 12:17



Par la norme - oui, ils sont différents:

  • Une directive de pré-traitement du formulaire

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

    recherche une séquence d'emplacements définis par l'implémentation pour un en-tête identifié uniquement par la séquence spécifiée entre < et > délimiteurs, et provoque le remplacement de cette directive par tout le contenu de l'en-tête. La façon dont les lieux sont spécifiés ou l'en-tête identifié est défini par l'implémentation.

  • Une directive de pré-traitement du formulaire

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

    provoque le remplacement de cette directive par tout le contenu du fichier source identifié par la séquence spécifiée entre le " délimiteurs. Le fichier source nommé est recherché d'une manière définie par l'implémentation. Si cette recherche n'est pas prise en charge ou si la recherche échoue, la directive est retraitée comme si elle était lue

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

    avec la séquence contenue identique (y compris > caractères, le cas échéant) de l'original   directif.

  • Une directive de pré-traitement du formulaire

    #include pp-tokens new-line
    

    (qui ne correspond pas à l'une des deux formes précédentes) est autorisé. Les jetons de prétraitement après include dans la directive sont traitées comme dans un texte normal. (Chaque identifiant actuellement défini en tant que nom de macro est remplacé par sa liste de remplacement de jetons de prétraitement.) La directive résultant de tous les remplacements doit correspondre à l'un des deux formulaires précédents. La méthode par laquelle une séquence de jetons de prétraitement entre un < et un > paire de jetons de prétraitement ou une paire de " Les caractères sont combinés en un seul nom d'en-tête. Le jeton de prétraitement est défini par l'implémentation.

Définitions

  • h-char: tout membre du jeu de caractères source sauf le caractère de nouvelle ligne et >

  • q-char: tout membre du jeu de caractères source sauf le caractère de nouvelle ligne et "

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 définie par l'implémentation (éventuellement autre). La norme spécifie également que certains fichiers include doivent être présents (par exemple, <stdio.h>).

Formellement vous auriez à lire le manuel pour votre compilateur, mais normalement (par tradition) le #include "..." formulaire recherche dans le répertoire du fichier dans lequel #include a été trouvé en premier, puis les répertoires que le #include <...> les recherches de formulaire (le chemin d'inclusion, par exemple les en-têtes de système).


16
2017-08-18 06:21



Merci pour les bonnes réponses, esp. Adam Stelmaszczyk et piCookie, et aib.

Comme beaucoup de programmeurs, j'ai utilisé la convention informelle d'utiliser le "myApp.hpp" formulaire pour les fichiers spécifiques à l'application, et <libHeader.hpp> formulaire pour les fichiers système de la bibliothèque et du compilateur, c'est-à-dire les fichiers spécifiés dans /I et le INCLUDE variable d'environnement, pendant des années en pensant que c'était la norme.

Cependant, la norme C stipule que l'ordre de recherche est spécifique à l'implémentation, ce qui peut compliquer la portabilité. Pour aggraver les choses, nous utilisons jam, qui détermine automatiquement où les fichiers include sont. Vous pouvez utiliser des chemins relatifs ou absolus pour vos fichiers d'inclusion. c'est à dire.

#include "../../MyProgDir/SourceDir1/someFile.hpp"

Les anciennes versions de MSVS nécessitaient des antislashs doubles (\\), mais ce n'est pas obligatoire. Je ne sais pas quand ça a changé. Utilisez juste des barres obliques pour la compatibilité avec 'nix (Windows acceptera cela).

Si vous êtes vraiment inquiet à ce sujet, utilisez "./myHeader.h" pour un fichier d'inclusion dans le même répertoire que le code source (mon projet actuel, très volumineux a des noms de fichiers d'inclusion en double dispersés - vraiment un problème de gestion de configuration).

Ici se trouve le MSDN explication copié ici pour votre commodité).

Formulaire cité

Le préprocesseur recherche les fichiers d'inclusion dans cet ordre:

  1. Dans le même répertoire que le fichier contenant l'instruction #include.
  2. Dans les répertoires des fichiers d'inclusion actuellement ouverts, dans l'ordre inverse dans lequel
        ils ont été ouverts. La recherche commence dans le répertoire du fichier include parent et
        continue vers le haut à travers les répertoires de tous les fichiers d'inclusion de grands-parents.
  3. Le long du chemin spécifié par chaque /I option du compilateur.
  4. Le long des chemins spécifiés par le INCLUDE variable d'environnement.

Forme de cornière

Le préprocesseur recherche les fichiers d'inclusion dans cet ordre:

  1. Le long du chemin spécifié par chaque /I option du compilateur.
  2. Lorsque la compilation se produit sur la ligne de commande, le long des chemins spécifiés par le INCLUDE variable d'environnement.

12
2017-10-14 23:51



Au moins pour la version GCC <= 3.0, la forme de crochet d'angle 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épendances (en utilisant l'option GCC -M par exemple), vous devez utiliser le formulaire quoté pour les fichiers qui doivent être inclus dans l'arbre de dépendance.

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


11
2017-10-25 12:35



Pour #include "" un compilateur recherche normalement le dossier du fichier qui contient cet include, puis les autres dossiers. Pour #include <> le compilateur ne recherche pas le dossier du fichier en cours.


10
2018-02-08 11:45