Сведения о вопросе

Martincow

08:18, 3rd August, 2020

Теги

В чем разница между #include и #include "filename"?

Просмотров: 985   Ответов: 25

В языках программирования C и C++ какая разница между использованием угловых скобок и использованием кавычек в операторе include , как показано ниже?

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



  Сведения об ответе

fo_I_K

00:46, 4th August, 2020

На практике разница заключается в местоположении, в котором препроцессор ищет включенный файл.

Для #include <filename> препроцессор выполняет поиск в зависимости от реализации, обычно в каталогах поиска, предварительно назначенных compiler/IDE. этот метод обычно используется для включения стандартных файлов заголовков библиотек.

Для #include "filename" препроцессор сначала выполняет поиск в том же каталоге, что и файл, содержащий директиву, а затем следует по пути поиска, используемому для формы #include <filename> . Этот метод обычно используется для включения определяемых программистом заголовочных файлов.

Более полное описание доступно в документации GCC по путям поиска .


  Сведения об ответе

davran

07:06, 28th August, 2020

Единственный способ узнать это-прочитать документацию по вашей реализации.

В стандарте C , раздел 6.10.2, пункты 2-4 гласят::

  • Директива предварительной обработки формы

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

    выполняет поиск последовательности определенных реализацией мест для заголовка , однозначно идентифицированного указанной последовательностью между разделителями < и > , и вызывает замену этой директивы всем содержимым заголовка . Способ указания мест или определения заголовка определяется реализацией.

  • Директива предварительной обработки формы

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

    вызывает замену этой директивы всем содержимым исходного файла , идентифицированного указанной последовательностью между разделителями " . Поиск именованного исходного файла выполняется в соответствии с определением реализации. Если этот поиск не поддерживается или поиск завершается неудачно, директива обрабатывается повторно, как если бы она считывала

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

    с идентичной содержимой последовательностью (включая > символа, если таковые имеются) из оригинала директива.

  • Директива предварительной обработки формы

    #include pp-tokens new-line
    

    (что не соответствует одной из двух предыдущих форм) разрешается. Токены предварительной обработки после include в директиве обрабатываются так же, как и в обычном тексте. (Каждый идентификатор, определяемый в настоящее время как имя макроса, заменяется соответствующим списком маркеров предварительной обработки.) Директива, полученная после всех замен, должна соответствовать одной из двух предыдущих форм. Метод, с помощью которого последовательность токенов предварительной обработки между парой токенов предварительной обработки < и > или парой символов " объединяется в один заголовок имени токена предварительной обработки, определяется реализацией.

Определение:

  • h-char: любой член исходного набора символов, кроме символа новой строки и >

  • q-char: любой член исходного набора символов, кроме символа новой строки и "


  Сведения об ответе

prince

11:17, 20th August, 2020

Последовательность символов между < и > однозначно относится к заголовку, который не обязательно является файлом. Реализации в значительной степени свободны использовать последовательность символов по своему усмотрению. (В основном, однако, просто рассматривайте его как имя файла и выполняйте поиск в пути включения , как указано в других сообщениях.)

Если используется форма #include "file" , реализация сначала ищет файл с заданным именем, если он поддерживается. Если нет (поддерживается ) или если поиск завершается неудачно, реализация ведет себя так, как если бы была использована другая форма ( #include <file>).

Кроме того, существует третья форма, которая используется, когда директива #include не соответствует ни одной из приведенных выше форм. В этой форме некоторая базовая предварительная обработка (например, расширение макроса) выполняется на "operands" директивы #include , и ожидается, что результат будет соответствовать одной из двух других форм.


  Сведения об ответе

DINO

01:23, 6th August, 2020

Некоторые хорошие ответы здесь ссылаются на стандарт C, но забыли стандарт POSIX, особенно специфическое поведение команды c99 (например, компилятор C) .

Согласно базовой спецификации открытой группы выпуск 7 ,

- Я в справочнике

Измените алгоритм поиска заголовков, имена которых не являются абсолютными путями, чтобы искать в каталоге, названном именем пути к каталогу , прежде чем искать в обычных местах. Таким образом, заголовки, имена которых заключены в двойные кавычки ( "" ), следует искать сначала в директории файла со строкой #include, затем в директориях с именем in -I options, а затем в обычных местах. Для заголовков, имена которых заключены в угловые скобки ("<>"), заголовок следует искать только в каталогах с именем in -I options, а затем в обычных местах. Каталоги с именем in -I options будут искать в указанном порядке. Реализации должны поддерживать не менее десяти экземпляров этой опции в одном вызове команды c99 .

Таким образом, в среде, совместимой с POSIX, с компилятором POSIX, совместимым с C , #include "file.h" , скорее всего, будет искать сначала ./file.h , где . -это каталог, в котором находится файл с инструкцией #include , а #include <file.h>, скорее всего, будет искать сначала /usr/include/file.h , где /usr/include -это обычные места для заголовков вашей системы (похоже, что они не определены POSIX).


  Сведения об ответе

SEEYOU

04:08, 11th August, 2020

GCC документация говорит следующее о различии между этими двумя:

Как пользовательские, так и системные заголовочные файлы включаются с помощью директивы предварительной обработки ‘#include’ . Он имеет два варианта исполнения:

#include <file>

Этот вариант используется для системных заголовочных файлов. Он ищет файл с именем file в стандартном списке системных каталогов. Вы можете добавить каталоги в этот список с параметром -I (см. вызов ).

#include "file"

Этот вариант используется для заголовочных файлов вашей собственной программы. Он ищет файл с именем file сначала в каталоге, содержащем текущий файл, затем в каталогах котировок, а затем в тех же каталогах, которые используются для <file> . Вы можете добавить каталоги в список каталогов котировок с параметром -iquote . Аргумент ‘#include’, разделенный кавычками или угловыми скобками, ведет себя как строковая константа, в которой комментарии не распознаются, а имена макросов не раскрываются. Таким образом, #include <x/*y> указывает на включение системного заголовочного файла с именем x/*y .

Однако если обратные косые черты встречаются в файле, они считаются обычными текстовыми символами, а не экранирующими символами. Ни один символ escape-последовательности, соответствующие строковые константы в C обрабатываются. Таким образом, #include "x\n\\y" указывает имя файла, содержащее три обратных косых черты. (Некоторые системы интерпретируют ‘ \ ' как разделитель пути. Все они также интерпретируют ‘/’ таким же образом. Он самый портативный, чтобы использовать только ‘/’ .)

Это ошибка, если в строке после имени файла есть что-либо (кроме комментариев).


  Сведения об ответе

прога

09:37, 5th August, 2020

Оно делает:

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

при этом . является либо каталогом файла, в котором содержится #include , и/или текущим рабочим каталогом компилятора, и / или default_include_paths

и

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

Если ./ находится в <default_include_paths>, то это не имеет значения.

Если mypath/myfile находится в другом каталоге include, поведение не определено.


  Сведения об ответе

прога

22:45, 24th August, 2020

Параметр <file> include указывает препроцессору искать сначала в каталогах -I и в предопределенных каталогах , а затем в каталоге файла .c. Параметр "file" include указывает препроцессору сначала выполнить поиск в каталоге исходного файла,а затем вернуться к параметру -I и предопределенному. Все пункты назначения так или иначе ищутся, только порядок поиска отличается.

Стандарт 2011 года в основном обсуждает включаемые файлы в "16.2 Source file inclusion".

2 директива предварительной обработки формы

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

выполняет поиск последовательности мест, определенных реализацией, для заголовка, однозначно идентифицированного пользователем. указанная последовательность между разделителями < и > и вызывает замена этой директивы всем содержимым заголовка. Как определяются места или определяется заголовок реализация-определена.

3 директива предварительной обработки формы

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

приводит к замене этой директивы всем содержимым исходного файла, идентифицированного указанная последовательность между " разделителями. В имени исходного файла поиск осуществляется в режиме, определяемом реализацией. Если этот поиск является не поддерживается, или если поиск завершается неудачно, директива повторно обрабатывается как если бы он читал

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

с идентичной содержимой последовательностью (включая символы>, если таковые имеются) из исходной директивы.

Обратите внимание, что форма "xxx" деградирует до формы <xxx> , если файл не найден. rest определяется реализацией.


  Сведения об ответе

lats

13:24, 4th August, 2020

По стандарту - да, они разные:

  • Директива предварительной обработки формы

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

    выполняет поиск последовательности определенных реализацией мест для заголовка, однозначно идентифицированного указанной последовательностью между разделителями < и > , и вызывает замену этой директивы всем содержимым заголовка. Способ указания мест или определения заголовка определяется реализацией.

  • Директива предварительной обработки формы

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

    вызывает замену этой директивы всем содержимым исходного файла, идентифицированного указанной последовательностью между разделителями " . Поиск именованного исходного файла выполняется в соответствии с определением реализации. Если этот поиск не поддерживается или поиск завершается неудачно, директива обрабатывается повторно, как если бы она считывала

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

    с идентичной содержимой последовательностью (включая > символа, если таковые имеются) из оригинала директива.

  • Директива предварительной обработки формы

    #include pp-tokens new-line
    

    (что не соответствует одной из двух предыдущих форм) разрешается. Токены предварительной обработки после include в директиве обрабатываются так же, как и в обычном тексте. (Каждый идентификатор, определяемый в настоящее время как имя макроса, заменяется соответствующим списком маркеров предварительной обработки.) Директива, полученная после всех замен, должна соответствовать одной из двух предыдущих форм. Метод, с помощью которого последовательность токенов предварительной обработки между парой токенов предварительной обработки < и > или парой символов " объединяется в один заголовок имени токена предварительной обработки, определяется реализацией.

Определение:

  • h-char: любой член исходного набора символов, кроме символа новой строки и >

  • q-char: любой член исходного набора символов, кроме символа новой строки и "

Обратите внимание, что стандарт не говорит о какой-либо связи между определенными способами реализации. Первая форма выполняет поиск одним способом, определенным реализацией, а вторая-другим (возможно, другим) способом, определенным реализацией. Стандарт также указывает, что некоторые включаемые файлы должны присутствовать (например, <stdio.h> ).

Формально вы должны были бы прочитать руководство для вашего компилятора, однако обычно (по традиции) форма #include "..." ищет каталог файла, в котором был найден #include , а затем каталоги, которые ищет форма #include <...> (путь включения, например системные заголовки).


  Сведения об ответе

davran

23:13, 3rd August, 2020

Спасибо за отличные ответы, ЭСП. Adam Stelmaszczyk и piCookie, а также aib.

Как и многие программисты, я использовал неформальное соглашение об использовании формы "myApp.hpp" для конкретных файлов приложений и формы <libHeader.hpp> для системных файлов библиотек и компиляторов, т. е. файлов, указанных в переменной окружения /I и INCLUDE , в течение многих лет думая, что это было стандартом.

Однако в стандарте C указано, что порядок поиска зависит от конкретной реализации, что может усложнить переносимость. Что еще хуже, мы используем jam, который автоматически вычисляет, где находятся включенные файлы. Вы можете использовать относительные или абсолютные пути для ваших включаемых файлов. т.е.

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

Более старые версии MSVS требовали двойной обратной косой черты ( \ \ ), но теперь это не требуется. Я не знаю, когда это изменилось. Просто используйте прямые косые черты для совместимости с 'nix (Windows примет это).

Если вы действительно беспокоитесь об этом, используйте "./myHeader.h" для включаемого файла в том же каталоге, что и исходный код (мой текущий, очень большой проект имеет несколько повторяющихся имен включаемых файлов, разбросанных по всему-действительно проблема управления конфигурацией).

Вот объяснение MSDN , скопированное здесь для вашего удобства).

Цитируемая форма

Препроцессор выполняет поиск включаемых файлов в следующем порядке:

  1. В том же каталоге, что и файл, содержащий инструкцию #include.
  2. В каталоги открытых в данный момент включаются файлы, в обратном порядке в которых
    они были открыты. Поиск начинается в директории родительского включаемого файла и
    продолжается вверх по каталогам любых дедушкиных файлов включения.
  3. По пути, указанному каждым параметром компилятора /I .
  4. Вдоль путей, указанных переменной окружения INCLUDE .

Форма угол-кронштейна

Препроцессор выполняет поиск включаемых файлов в следующем порядке:

  1. По пути, указанному каждым параметром компилятора /I .
  2. При компиляции происходит в командной строке, по путям, указанным переменной окружения INCLUDE .


  Сведения об ответе

qwerty101

01:43, 15th August, 2020

По крайней мере, для GCC версии <= 3.0 форма угловой скобки не создает зависимости между включенным файлом и включающим файлом.

Поэтому, если вы хотите создать правила зависимостей (используя параметр GCC-M для exemple), вы должны использовать форму в кавычках для файлов, которые должны быть включены в дерево зависимостей.

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


  Сведения об ответе

PIRLO

00:02, 18th August, 2020

Для #include "" компилятор обычно ищет папку файла, который содержит этот include, а затем другие папки. Для #include <> компилятор не выполняет поиск в папке текущего файла.


  Сведения об ответе

PIRLO

04:16, 14th August, 2020

При использовании #include <filename>, препроцессор ищет файл в каталоге заголовочных файлов C\C++ (stdio.h\cstdio, string, vector и др.). Но, когда вы используете #include "filename": во-первых, препроцессор ищет файл в текущем каталоге, а если его здесь нет - он ищет его в каталоге заголовочных файлов C\C++.


  Сведения об ответе

fo_I_K

02:54, 10th August, 2020

#include <file.h> указывает компилятору искать заголовок в его каталоге "includes", например, для MinGW компилятор будет искать file.h в C:\MinGW\include\ или везде, где установлен ваш компилятор.

#include "file" указывает компилятору искать текущий каталог (т. е. каталог, в котором находится исходный файл) для file .

Вы можете использовать флаг -I для GCC, чтобы сообщить ему, что, когда он сталкивается с включением с угловыми скобками, он также должен искать заголовки в каталоге после -I . GCC будет обрабатывать каталог после флага, как если бы это был каталог includes .

Например, если у вас есть файл с именем myheader.h в вашем собственном каталоге, вы можете сказать #include <myheader.h> , если вы вызвали GCC с флагом -I . (указывая, что он должен искать includes в текущем каталоге.)

Без флага -I вам придется использовать #include "myheader.h" для включения файла или переместить myheader.h в каталог include вашей компиляции.


  Сведения об ответе

LAST

13:19, 2nd August, 2020

  • #include <> предназначен для предопределенных заголовочных файлов

Если файл заголовка предопределен, то вы просто напишете имя файла заголовка в скобках angular, и это будет выглядеть так (предполагая, что у нас есть предопределенное имя файла заголовка iostream):

#include <iostream>
  • #include " " - это для заголовочных файлов, которые определяет программист

Если бы вы (программист) написали свой собственный файл заголовка, то вы бы написали имя файла заголовка в кавычках. Итак, предположим, что вы написали заголовочный файл с именем myfile.h , то это пример того, как вы будете использовать директиву include для включения этого файла:

#include "myfile.h"


  Сведения об ответе

crush

11:30, 9th August, 2020

#include с угловыми скобками будет искать "implementation-dependent list of places" (что является очень сложным способом сказать "системные заголовки") для файла, который будет включен.

#include с кавычками будет просто искать файл (и, "в зависимости от реализации", bleh). Это означает, что на нормальном английском языке он попытается применить путь / имя файла, который вы бросаете в него, и не будет добавлять системный путь или вмешиваться в него иначе.

Кроме того, если #include "" терпит неудачу, он перечитывается как #include <> по стандарту.

Документация gcc имеет описание (специфичное для компилятора), которое, хотя и относится к gcc, а не к стандарту, гораздо легче понять, чем разговоры в стиле адвоката о стандартах ISO.


  Сведения об ответе

piter

18:08, 18th August, 2020

#include "filename" // User defined header
#include <filename> // Standard library header.

Пример:

Имя файла здесь 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

В реализации класса (например, Seller.cpp и в других файлах , которые будут использовать файл Seller.h) теперь должен быть включен заголовок, определенный пользователем, следующим образом:

#include "Seller.h"


  Сведения об ответе

lool

02:33, 6th August, 2020

Многие ответы здесь сосредоточены на путях, которые компилятор будет искать, чтобы найти файл. Хотя это то, что делает большинство компиляторов, соответствующий компилятор может быть предварительно запрограммирован с эффектами стандартных заголовков и рассматривать, скажем, #include <list> как коммутатор, и он вообще не должен существовать как файл.

Это не чисто гипотетическое предположение. Существует по крайней мере один компилятор, который работает таким образом. Рекомендуется использовать #include <xxx> только со стандартными заголовками.


  Сведения об ответе

Chhiki

11:56, 12th August, 2020

#include <abc.h>

используется для включения стандартных библиотечных файлов. Таким образом, компилятор будет проверять расположение стандартных заголовков библиотек.

#include "xyz.h"

скажет компилятору включить определяемые пользователем заголовочные файлы. Таким образом, компилятор будет проверять наличие этих заголовочных файлов в текущей папке или -I определенных папках.


  Сведения об ответе

pumpa

07:45, 12th August, 2020

В C++ включить файл можно двумя способами:

Первый - это #include, который говорит препроцессору искать файл в предопределенном местоположении по умолчанию. Это расположение часто является переменной среды INCLUDE, которая обозначает путь к включаемым файлам.

И второй тип-это #include "filename", который говорит препроцессору сначала искать файл в текущем каталоге, а затем искать его в заранее определенных местах, которые пользователь настроил.


  Сведения об ответе

SEEYOU

04:50, 27th August, 2020

функция "< filename >" выполняет поиск в стандартных расположениях библиотеки C

тогда как "filename" выполняет поиск и в текущем каталоге.

В идеале, вы бы использовали <...> для стандартных библиотек C и "..."для библиотек, которые вы пишете и которые присутствуют в текущем каталоге.


  Сведения об ответе

SKY

19:41, 27th August, 2020

#include <filename> используется при обращении к системному файлу. Это заголовочный файл, который можно найти в расположениях системы по умолчанию, таких как /usr/include или /usr/local/include . Для ваших собственных файлов, которые должны быть включены в другую программу, вы должны использовать синтаксис #include "filename" .


  Сведения об ответе

padenie

17:06, 27th August, 2020

Простое общее правило заключается в использовании угловых скобок для включения заголовочных файлов, которые поставляются с компилятором. Используйте двойные кавычки для включения любых других заголовочных файлов. Большинство компиляторов делают это именно так.

1.9-заголовочные файлы более подробно описывают директивы препроцессора. Если вы начинающий программист, эта страница должна помочь вам понять все это. Я научился этому здесь, и я следовал этому на работе.


  Сведения об ответе

SILA

03:56, 1st August, 2020

#include <filename>

используется, когда требуется использовать заголовочный файл системы C/C++ или библиотеки компилятора. Эти библиотеки могут быть stdio.h, string.h, math.h, и т. д.

#include "path-to-file/filename"

используется, когда вы хотите использовать свой собственный пользовательский файл заголовка, который находится в папке вашего проекта или где-то еще.

Для получения дополнительной информации о препроцессорах и заголовке. Читать C-Препроцессоры .


  Сведения об ответе

#hash

19:17, 18th August, 2020

Форма 1 - #include "xxx"

Во-первых, ищет наличие файла заголовка в текущем каталоге, из которого вызывается директива. Если не найден, то он ищет в предварительно настроенном списке стандартных системных каталогов.

Форма 2-#include < xxx >

Это ищет наличие файла заголовка в текущем каталоге,из которого вызывается директива.


Точный список каталогов поиска зависит от целевой системы, способа настройки GCC и места его установки. Вы можете найти список каталогов поиска вашего компилятора GCC, запустив его с опцией-v.

Вы можете добавить дополнительные каталоги в путь поиска с помощью параметра - I dir, который вызывает поиск dir после текущего каталога (для формы цитаты директивы) и перед стандартными системными каталогами.


В принципе, форма "xxx" - это не что иное, как поиск в текущем каталоге; если форма не найдена, она возвращается назад


  Сведения об ответе

P_S_S

06:59, 4th August, 2020

Чтобы просмотреть порядок поиска в вашей системе с помощью gcc, основываясь на текущей конфигурации , вы можете выполнить следующую команду. Вы можете найти более подробную информацию об этой команде здесь

cpp -v /dev/null -o /dev/null

Apple LLVM версия 10.0.0 (clang-1000.10.44.2)
Цель: x86_64-apple-darwin18.0.0
Модель резьбы: posix InstalledDir: Library/Developer/CommandLineTools/usr/bin
"/Library/Developer/CommandLineTools/usr/bin/clang" - cc1-тройной архитектуру x86_64-яблоко-macosx10.14.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -е -отключить-бесплатно -disable-llvm-verifier -discard-value-names -main-file-name null -mrelocation-модель пик -пик-уровень 2 -mthread-модель posix -mdisable-fp-elim -fno-strict-return -компилятор MASM-подробный munwind-столы -цель-cpu Пенрин -dwarf-column-info -отладчик-тюнинг=символы отладки -target-linker-version 409.12 -в-ресурс-реж /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-предел 19 -fmessage-длина 80 -стек-протектор 1 -fblocks -fencode-extended-block-signature -fobjc-среда=в MacOSX-10.14.0 -fmax-type-align=16 -fdiagnostics-show-option -чернилами fcolor-диагностика -традиционный ЧГК -о - -Х c /dev/null
clang-cc1 версия 10.0.0 (clang-1000.10.44.2) цель по умолчанию x86_64-apple-darwin18.0.0 игнорирование несуществующий каталог "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/local/include" игнорирование несуществующего каталога "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/Library/Frameworks"
#include"...- поиск начинается здесь:
#include <...> поиск начинается здесь:
/usr/local/include
/Library/Developer/CommandLineTools/usr/lib/clang/10.0.0/include
/Library/Developer/CommandLineTools/usr/include
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/System/Library/Frameworks (каталог фреймворка)
Конец списка поиска.


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться