В чем разница между #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?
Почему используются #ifndef и #define в заголовочных файлах C++?
Разница между const int*, const int * const и int * const?
Почему переменные нельзя объявлять в операторе switch?
`unsigned int` против `size_t`: когда и что использовать?