В чем разница между #include <filename> и #include "filename"?
В чем разница между использованием угловых скобок и кавычек в директиве include
?
#include <filename>
#include "filename"
5 ответ(ов)
Секвенция символов между < и > уникально ссылается на заголовок, который не обязательно является файлом. Реализации в основном имеют свободу использовать эту последовательность символов по своему усмотрению. Однако, как правило, она рассматривается как имя файла, и осуществляется поиск в пути включения, как упоминается в других ответах.
Если используется форма #include "file"
, реализация сначала ищет файл с указанным именем, если это поддерживается. Если не поддерживается или если поиск не удался, реализация ведет себя так, как будто используется другая форма (#include <file>
).
Также существует третья форма, которая используется, когда директива #include
не соответствует ни одной из указанных выше форм. В этой форме выполняется некоторый базовый предварительный процессинг (например, расширение макросов) для "операндов" директивы #include
, и ожидается, что результат будет соответствовать одной из двух других форм.
Точное поведение препроцессора может различаться между компиляторами. Следующий ответ применим к GCC и нескольким другим компиляторам.
#include <file.h>
указывает компилятору искать заголовочный файл в директории "includes", например, для MinGW компилятор будет искать file.h
в C:\MinGW\include\ или в той директории, где установлен ваш компилятор.
#include "file"
говорит компилятору искать файл в текущей директории (т.е. в директории, где находится исходный файл).
Вы можете использовать флаг -I
для GCC, чтобы указать компилятору, что при встрече #include
с угловыми скобками он также должен искать заголовки в директории, указанной после -I
. GCC будет рассматривать директорию после флага как директорию includes
.
Например, если у вас есть файл myheader.h
в вашей директории, вы можете использовать #include <myheader.h>
, если вызовете GCC с флагом -I .
(что указывает на поиск заголовков в текущей директории).
Без флага -I
вам придется использовать #include "myheader.h"
для подключения файла или переместить myheader.h
в директорию include
вашего компилятора.
Это действительно так:
"mypath/myfile" сокращенно обозначает ./mypath/myfile
где .
означает либо директорию файла, в которой находится #include
, и/или текущую рабочую директорию компилятора, и/или default_include_paths
.
А `
<mypath/myfile> сокращенно обозначает <defaultincludepaths>/mypath/myfile
Если ./
находится в <default_include_paths>
, то разницы нет.
Если mypath/myfile
находится в другой директории включения, поведение считается неопределенным.
Включение файла с помощью конструкции <file>
указывает препроцессору сначала искать в директориях, указанных с помощью флага -I
, а также в предопределенных директориях, а затем уже в директории, где находится .c файл. В то время как включение с помощью "file"
заставляет препроцессор сначала искать в директории исходного файла, а затем переходить к -I
и предопределенным директориям. Таким образом, все места поиска будут исследованы, но порядок поиска различается.
Стандарт 2011 года в основном обсуждает включение файлов в разделе "16.2 Включение исходных файлов".
2 Препроцессорная директива формы
# include <h-char-sequence> новая-строка
ищет последовательность мест, определяемых реализацией, для заголовка, уникально идентифицированного указанной последовательностью между ограничителями
<
и>
, и заменяет эту директиву на полное содержимое заголовка. Как именно определяется место или идентифицируется заголовок, зависит от реализации.3 Препроцессорная директива формы
# include "q-char-sequence" новая-строка
заменяет эту директиву на полное содержимое исходного файла, идентифицированного указанной последовательностью между ограничителями
"
. Именованный исходный файл ищется в порядке, определяемом реализацией. Если этот поиск не поддерживается или если поиск не удался, директива обрабатывается повторно так, как если бы она содержала
# include <h-char-sequence> новая-строка
с идентичной содержательной последовательностью (включая символы
>
, если таковые имеются) из оригинальной директивы.
Обратите внимание, что форма "xxx"
деградирует до формы <xxx>
, если файл не найден. Остальное определяется реализацией.
Да, по стандарту они различаются:
Директива препроцессора вида
#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 <...>
(путь включения, например, системные заголовки).
Почему в макросах используются, казалось бы, бессмысленные операторы do-while и if-else?
Как изменить цвет вывода echo в Linux
Каково влияние extern "C" в C++?
Разница между const int*, const int * const и int * const?
Является ли < быстрее, чем <=?