[C++] В чем разница между #include <filename> и #include "filename"?


Answers

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

В стандарте 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: любой член набора символов источника, кроме символа новой строки, и "

Question

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

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



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

В соответствии с базовыми спецификациями Open Group Issue 7 ,

-I каталог

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

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




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

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

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




#include <file> tells the compiler to search for the header in its includes directory, eg for MinGW the compiler would search for file in C:\MinGW\include\ or wherever your compiler is installed.

#include "file" tells the compiler to search the current directory (ie the directory in which the source file resides) for file .

You can use the -I flag for GCC to tell it that, when it encounters an include with angled brackets, it should also search for headers in the directory after -I . For instance, if you have a file called myheader.h in your own directory, you could say #include <myheader.h> if you called GCC with -I . (indicating that it should search for includes in the current directory.)




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

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

#include <file>

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

#include "file"

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

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

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




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

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

    #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 <...> поиск формы (включить путь, например системные заголовки).




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

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

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

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




When you use #include <filename>, the pre-processor looking for the file in directtory of C\C++ header files (stdio.h\cstdio, string, vector, etc.). But, when you use #include "filename": first, the pre-processor looking for the file in the current directory, and if it doesn't here - he looking for it in the directory of C\C++ header files.




#include <filename>

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

#include "path-to-file/filename"

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

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




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

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

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

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

#include "myfile.h"



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




  #include <filename>   (1)     
  #include "filename"   (2)

#include включает исходный файл, идентифицированный по имени файла, в текущий исходный файл на строке сразу после директивы.

Первая версия директивы ищет только стандартные каталоги. Стандартная библиотека C ++, а также стандартная библиотека C неявно включены в стандартные каталоги include. Стандартные каталоги могут управляться пользователем через параметры компилятора.

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

В случае, если файл не найден, программа плохо сформирована.




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

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

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




#include <filename>

will find the corresponding file from the C++ library. it means if you have a file called hello.h in the C++ library folder, #include <hello.h> will load it.

Но,

#include "filename"

will find the file in the same directory where your source file is.

In addition,

#include "path_to_file/filename"

will find the file in the directory which you typed in path_to_file .