31

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

12

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

  • #include <filename>
  • #include "filename"

5 ответ(ов)

3

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

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

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

0

Точное поведение препроцессора может различаться между компиляторами. Следующий ответ применим к 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 вашего компилятора.

0

Это действительно так:

"mypath/myfile" сокращенно обозначает ./mypath/myfile

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

А `

<mypath/myfile> сокращенно обозначает <defaultincludepaths>/mypath/myfile

Если ./ находится в <default_include_paths>, то разницы нет.

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

0

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

Стандарт 2011 года в основном обсуждает включение файлов в разделе "16.2 Включение исходных файлов".

2 Препроцессорная директива формы

# include <h-char-sequence> новая-строка

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

3 Препроцессорная директива формы

# include "q-char-sequence" новая-строка

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

# include <h-char-sequence> новая-строка

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

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

0

Да, по стандарту они различаются:

  • Директива препроцессора вида

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

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