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

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

  1. #include <filename>
  2. #include "filename"
22.08.2008 01:40:06
Для поведения Visual Studio, пожалуйста, проверьте: docs.microsoft.com/en-us/cpp/preprocessor/…
smwikipedia 17.03.2020 05:58:55
28 ОТВЕТОВ

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

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

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

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

1376
16.01.2018 16:12:29
Утверждение: «препроцессор выполняет поиск в том же каталоге ...» может быть верным на практике, но стандарт гласит, что указанный исходный файл «ищется в соответствии с реализацией». Смотрите ответ от piCookie.
Richard Corden 17.09.2008 13:41:58
Хотя ваш ответ может показаться «верным», потому что именно так много реализаций работают по соглашению, вы должны внимательно посмотреть на ответы aib и piCookie. Они оба указывают (опираясь на формулировку стандарта C), что реальное различие заключается во включении «заголовка» и «исходного файла» (и нет, это не означает «.h» против ». с "). «Исходный файл» в этом контексте может быть (и обычно является, и почти всегда должен быть) файлом «.h». Заголовок не обязательно должен быть файлом (например, компилятор может включать заголовок, который статически закодирован, а не в файле).
Dan Moulding 17.08.2009 16:30:56
«... препроцессор ищет в том же каталоге, что и файл, который компилируется, для включения файла». Это утверждение не совсем правильно. Меня заинтересовал этот вопрос, потому что мне было любопытно, каков на самом деле ответ, но я знаю, что это не так, потому что, по крайней мере, с помощью gcc, когда вы указываете дополнительный путь включения с -I, который будет искать файлы, указанные с именем #include. h "
Gabriel Southern 12.03.2012 21:49:42
Тем, кому не нравится ответ, приведите один практический пример, где он неправильный.
0kcats 8.11.2017 20:46:40
Конечно же, недавно я смешал эти синтаксисы, когда включал заголовки из «той же» библиотеки, и в результате получил ошибки переопределения. Если я правильно понял, #include <...>использовал пакет, установленный в системе, и #include "..."версию соседнего репозитория. Я мог бы иметь это задом наперед. В любом случае, защита включения в упакованном заголовке имеет префикс подчеркивания. (Это может быть соглашение о пакетах или способ преднамеренно предотвратить смешивание двух, хотя для меня было бы лучше иметь смысл классификаторы версий.)
John P 23.02.2018 00:21:33

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

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

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

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

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

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

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

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

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

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

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

37
28.12.2014 18:25:27
Не могли бы вы дать ссылку на то, где в стандарте C -Iуказан этот бизнес?
juanchopanza 28.12.2014 04:31:32
Я не вижу ссылки на -I.
juanchopanza 28.12.2014 18:49:15
Это часть, определяемая реализацией.
user3458 29.12.2014 14:40:40

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

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

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

282
22.04.2013 16:06:58
+1, это, пожалуй, самый краткий и правильный ответ здесь. Согласно стандарту (который цитирует piCookie в своем ответе), единственная реальная разница - это «заголовок» и «исходный файл». Механизм поиска определяется реализацией в любом случае. Использование двойных кавычек означает, что вы намереваетесь включить «исходный файл», а угловые скобки означают, что вы намереваетесь включить «заголовок», который, как вы говорите, может вообще не быть файлом.
Dan Moulding 17.08.2009 16:12:17
Посмотрите комментарий Дэна Молдинга к ответу на квест49; стандартные заголовки не обязательно должны быть в форме файла, они могут быть встроенными.
aib 27.01.2011 09:28:45
Я читал это "стандартные заголовки не должны быть в форме файла" в течение десятилетия. Хотите привести пример из реальной жизни?
Maxim Egorushkin 8.02.2011 11:54:18
@ Максим Егорушкин: Я не могу вспомнить ни одного из существующих примеров из реальной жизни; тем не менее, полноценный компилятор C11 не может существовать для MS-DOS, если заголовки не должны быть файлами. Это связано с тем, что некоторые имена заголовков C11 несовместимы с ограничением имени файла MS-DOS «8.3».
Dan Moulding 12.10.2012 12:35:07
@MaximEgorushkin: Компилятор C VAX / VMS хранил все заголовки библиотеки времени выполнения C в одном текстовом файле библиотеки (подобно архиву unix) и использовал строку между <и >в качестве ключа для индексации в библиотеке.
Adrian McCarthy 15.02.2017 23:14:52

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

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

706
15.01.2019 16:46:56
Актуально: реализация в g ++ и в Visual C ++
Alexander Malakhov 10.10.2012 03:48:31
@piCookie и <filename>, и "filename" ищут места, определенные реализацией. Так в чем же разница?
onmyway133 4.02.2013 03:45:17
@ Стефан, я просто цитирую стандарт, который ничего не говорит о INCLUDE_PATH. Ваша реализация может сделать это, а моя - нет. Первоначальный вопрос был, в общем, C, а не gcc (который, я думаю, использует INCLUDE_PATH), Microsoft C (что, я думаю, делает) или любой другой, поэтому на него нельзя ответить в общем, но вместо этого следует ссылаться на документацию каждой реализации.
piCookie 25.08.2013 00:22:44
Как и во всех этих ситуациях, конкретные примеры (особенно общих сценариев) очень полезны и одинаково оценены. Излишне тупые общие ответы не имеют такого большого практического применения.
vargonian 29.04.2014 17:51:42
«Вот как стандарт С может быть многословным и не отвечать на ваш вопрос»
anatolyg 29.03.2015 19:32:50

Оно делает:

"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, поведение не определено.

44
6.09.2016 09:04:29
Нет, #include "mypath/myfile"не является эквивалентом #include "./mypath/myfile". Как говорится в ответе piCookie, двойные кавычки указывают компилятору выполнять поиск в соответствии с реализацией, что включает в себя поиск в указанных местах #include <...>. (На самом деле, это, вероятно, эквивалентно, но только потому, что, например, его /usr/include/mypath/myfileможно назвать /usr/include/./mypath/myfile- по крайней мере, в Unix-подобных системах.)
Keith Thompson 7.09.2011 23:03:28
@ Кит Томпсон: Правильно, я думал о своей коробке Linux. Очевидно, это может быть по-другому. Хотя на практике Windows как не-Posix операционная система также интерпретирует / как разделитель пути, и ./ также существует.
Stefan Steiger 3.04.2014 09:23:03
опция -L dirpath добавляет dirpath к defaultincludepaths, а не дает другое значение .(как указано выше). Это имеет ожидаемое следствие того, что оба #include "..."и #include <...>ищут в dirpath
Protongun 6.04.2014 18:07:25
Я думаю, что этот ответ неверен, поскольку подразумевает, что заголовки, включенные в двойные кавычки, всегда ищутся в текущем рабочем каталоге. Механизм поиска более детален; этот ответ неполон. Я не добавляю этот комментарий, чтобы жаловаться или скулить, но потому что система просит меня добавить комментарий, чтобы объяснить, почему я проголосовал за этот ответ.
Carlo Wood 27.09.2016 23:06:00

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

14
25.07.2015 15:29:19
Не уверен, почему люди не согласны.
Maxim Egorushkin 27.03.2012 06:30:01
Я подозреваю, что это потому, что большинство людей компилируют только файлы в своем CWD. Если вы находитесь в каталоге foo и компилируете foo / unittest / bar.c, и он включает bar.h, тогда «bar.h» работает, а <bar.h> - нет.
user3458 30.03.2012 14:07:14
@ Максим люди не согласны, потому что описанное вами поведение не является стандартным C.
osvein 25.07.2015 12:16:02
@Spookbuster Правильно, стандарт говорит и то <filename>и другое и "filename"ищет места, определенные реализацией.
Maxim Egorushkin 17.09.2016 13:33:28

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

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

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

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

11
8.02.2011 12:02:32
Однако использование угловых скобок или кавычек не влияет на способ включения файлов, оно точно такое же: препроцессор по сути создает большой исходный файл путем копирования и переноса кода из включаемых файлов в исходный исходный файл перед предоставлением это компилятору (препроцессор делает другое, например, #define sustitution, #if вычисление и т. д., но обработка #include так проста)
Loghorn 8.02.2011 12:59:26
А как насчет конфликтов? например, я говорю zlib.hв моих путях поиска «пользователя», и в пути поиска системы существует другая версия, тогда #include <zlib.h>включает ли версию системы и #include "zlib.h"мою собственную?
the_mandrill 8.02.2011 13:10:06
Ага, ответил на мой собственный вопрос: stackoverflow.com/questions/21593/…
the_mandrill 8.02.2011 13:10:40
Спасибо за признание того, что и стандарт (ы), и типичные соглашения о реализации здесь важны, а не просто заявляют, что это непостижимо, потому что это не определено стандартом.
Kyle Strand 27.07.2016 17:45:45
#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"
10
21.11.2017 21:47:44

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

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

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

15
25.10.2011 12:35:25
Да, есть несколько разных способов создания зависимостей. Это один из них, но не единственный.
Pryftan 21.11.2019 23:01:13

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

В соответствии с Открытой группой Базовые спецификации, выпуск 7 ,

-I каталог

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

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

112
12.03.2015 05:29:33
Каков точный источник текста? Это из нормативной части IEEE Std 1003.1, 2013?
osgx 12.03.2015 02:34:32
@osgx: эта формулировка (или что-то очень похожее) находится в спецификации POSIX для c99- которая является именем POSIX для компилятора C. (Стандарт POSIX 2008 едва ли мог ссылаться на C11; обновление 2013 года для POSIX 2008 не изменило стандарт C, на который он ссылался.)
Jonathan Leffler 10.11.2016 03:40:37
Это была моя первая мысль тоже. Manpage для gcc включает это, как и другие. Там также похожая вещь для библиотек -L.
Pryftan 21.11.2019 22:55:34
  • #include <> для предопределенных заголовочных файлов

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

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

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

#include "myfile.h"
10
6.03.2018 19:22:43
Это не имеет ничего общего с предварительно определенными заголовочными файлами. Это связано с местами для поиска.
C Johnson 23.04.2019 15:29:42

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

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

5
1.01.2016 20:33:49

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

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

9
30.05.2017 10:19:46

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

6
27.08.2014 19:36:49

Спасибо за отличные ответы, особенно Адам Стельмащик и ПиКуки, и аиб.

Как и многие программисты, я использовал неофициальное соглашение использования "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переменной среды.
16
10.11.2016 04:08:06
#include <filename>

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

#include "path-to-file/filename"

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

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

4
23.08.2016 10:38:29

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

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

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

20
28.07.2016 07:25:35
В основном это тот же текст, что и в ответе piCookie за семь лет до этого.
Kyle Strand 27.07.2016 17:43:55
@KyleStrand Это потому, что тот же текст является цитатой соответствующего раздела в стандарте - этот текст должен быть идентичным. Фактический ответ не совпадает с текстом и несколько отличается - хотя я также признаю, что он будет записан в документации по реализации, я также отмечаю, что существует также традиционный способ их интерпретации (что большинство или все компиляторы, которые я использовал, уважают) ,
skyking 28.07.2016 07:25:10
IMO, это лучший ответ здесь, потому что он охватывает и то, что говорит стандарт, и то, что фактически делает большинство компиляторов.
plugwash 11.09.2016 13:59:59

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

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

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

7
10.07.2016 00:44:00

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

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

#include <file>

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

#include "file"

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

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

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

47
21.11.2017 21:51:16
#include <abc.h>

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

#include "xyz.h"

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

9
21.11.2017 21:53:33

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

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

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

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

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

21
21.03.2020 22:41:25

поиск <filename> в стандартных местах библиотеки C

тогда как «имя файла» ищет и в текущем каталоге.

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

6
28.03.2018 11:35:39
Какая новая информация добавляет этот ответ к другим?
Daniel Langr 28.03.2018 11:40:20

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

13
8.11.2018 03:32:32
После того, как идеальный ответ был доступен в течение многих лет, зачем его отправлять, это просто явно неправильно? Несмотря на то, что #includeдиректива обычная, она вообще не связана с файлами.
IInspectable 2.10.2018 19:31:44
@IInspectable, пожалуйста, объясните, почему это вообще не связано с файлами.
Behrooz Karjoo 26.02.2019 20:06:12

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

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

Форма 2 - #include "ххх"

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


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

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


По сути, форма «xxx» - это не что иное, как поиск в текущем каталоге; если не найдено, возвращаясь к форме

7
12.07.2019 05:49:33
Если вы решите ответить на старый вопрос, на котором уже есть точные и правильные ответы, добавление нового ответа в конце дня может не принести вам никакой пользы. Если у вас есть какая-то новая отличительная информация или вы убеждены, что все остальные ответы неверны, обязательно добавьте новый ответ, но «еще один ответ», дающий ту же основную информацию спустя долгое время после того, как вопрос был задан, обычно выигрывает ». Я не заработаю тебе много кредитов.
Jonathan Leffler 13.07.2019 05:27:20
@Jonathan Leffler Можете ли вы указать мне на «хорошо обоснованный» ответ, который, по вашему мнению, является таким же кратким и точным, как и ответ Даршана?
personal_cloud 13.07.2019 05:36:49
Описание #include "header.h"формы не точное, @personal_cloud. Я считаю ответ piCookie и Yann Droneaud наиболее актуальным, поскольку они определяют, откуда поступает их информация. Я не считаю, что голосование с наивысшим рейтингом также является полностью удовлетворительным.
Jonathan Leffler 13.07.2019 06:05:27
Почему этот ответ показан сверху, а два ответа ниже - более 650 голосов? Этот ответ смутил меня, потому что он не соответствует наблюдаемому мной поведению. Это может быть связано с тем, что последнее предложение не соответствует угловым скобкам. Я не уверен, что это должно означать.
Neonit 1.08.2019 15:37:38

Существует два способа написать заявление #include. Это:

#include"filename"
#include<filename>

Смысл каждой формы

#include"mylib.h"

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

#include<mylib.h>

Эта команда будет искать файл только mylib.hв указанном списке каталогов.

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

-2
18.08.2018 09:24:23
Если вы решите ответить на старый вопрос, на котором уже есть точные и правильные ответы, добавление нового ответа в конце дня может не принести вам никакой пользы. Если у вас есть какая-то новая отличительная информация или вы убеждены, что все остальные ответы неверны, обязательно добавьте новый ответ, но «еще один ответ», дающий ту же основную информацию спустя долгое время после того, как вопрос был задан, обычно выигрывает ». Я не заработаю тебе много кредитов.
Jonathan Leffler 13.07.2019 05:26:07

Чтобы увидеть порядок поиска в вашей системе с помощью 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 УстановленныйDir: Библиотека / Разработчик / CommandLineTools / usr / bin
"/ Библиотека / Разработчик / CommandLineTools / usr / bin / clang" -cc1 -triple x86_64-apple-macosx10.14.0 -Wdeprecated-objc-isa-use -Werror = не рекомендуется-objc-isa-use -E -disable-free - отключить-llvm-верификатор -discard-value-names -main-file-name null -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -fno-strict-return -masm-verbose - munwind-tables -target-cpu penryn -dwarf-column-info -debugger-tuning = lldb -target-linker-version 409.12 -v -resource-dir /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-limit 19 -fmessage-length 80 -stack-protector 1 -fblocks -fencode-extended-block-signature -fobjc-runtime = macosx-10.14.0 -fmax-type-align = 16 -fdiagnostics-show-option -fcolor-диагностика -traditional-cpp -o - -xc / 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" игнорирование несуществующего directory "/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 (каталог платформы)
Конец списка поиска.

2
3.10.2018 18:51:45

#include <filename>

  • Препроцессор выполняет поиск в зависимости от реализации. Он сообщает компилятору искать каталог, в котором хранятся файлы заголовков системы.
  • Этот метод обычно используют для поиска стандартных заголовочных файлов.

#include "filename"

  • Это говорит компилятору искать заголовочные файлы, где работает программа. В случае неудачи он ведет себя как #include <filename>и ищет этот заголовочный файл, где хранятся системные заголовочные файлы.
  • Этот метод обычно используется для идентификации пользовательских файлов заголовков (файлов заголовков, которые создаются пользователем). Не используйте это, если вы хотите вызвать стандартную библиотеку, потому что она требует больше времени на компиляцию, чем #include <filename>.
3
27.12.2019 05:18:22
#include <file> 

Включает файл, в котором каталог по умолчанию включен.

#include "file" 

Включает файл в текущем каталоге, в котором он был скомпилирован.

0
1.03.2020 23:11:34