Яка різниця між #include <ім'ям файлу> та #include "ім'ям файлу"?


2354

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

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



Що стосується поведінки Visual Studio, перевірте: docs.microsoft.com/en-us/cpp/preprocessor/…
smwikipedia

Відповіді:


1404

На практиці різниця полягає в розташуванні, де препроцесор шукає включений файл.

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

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

Більш повний опис є в документації GCC про пошукові шляхи .


135
Заява: "препроцесор здійснює пошук у тому самому каталозі ..." на практиці може бути правдивим, але стандарт стверджує, що названий вихідний файл "шукається у визначеному реалізацією способі". Дивіться відповідь від piCookie.
Річард Корден

60
Незважаючи на те, що ваша відповідь може здатися "правдивою", оскільки саме така кількість реалізацій працює за домовленістю, вам слід уважно ознайомитися з відповідями aib та piCookie. Вони обидва зазначають (підкріплені формулюванням стандарту C), що справжня відмінність - це включення "заголовка" проти включення "вихідного файлу" (і ні, це не означає ".h" vs. " в "). "Вихідний файл" в цьому контексті може бути (і зазвичай є, і майже завжди повинен бути) ".h" файлом. Заголовок не обов'язково повинен бути файлом (компілятор може, наприклад, включати заголовок, який статично закодований, а не у файлі).
Дан Ліплення

5
"... препроцесор здійснює пошук у тому самому каталозі, що і файл, який складається для включення файлу." Це твердження не зовсім коректно. Мене це питання зацікавило, тому що мені було цікаво, що насправді відповідає, але я знаю, що це неправда, тому що принаймні з gcc, коли ви вказуєте додатковий, включайте шлях з -I, який буде шукати файли, вказані з ім'ям файлу #include. ч »
Габріель Саузерн

9
Тим, хто не подобається відповіді, будь ласка, наведіть один практичний приклад, коли це неправильно.
0kcats

1
Звичайно, я нещодавно змішав ці синтаксиси, включаючи заголовки з "тієї ж" бібліотеки і закінчився помилками переосмислення. Якщо я правильно розумію, #include <...>використовував пакет, встановлений у системі, і #include "..."використовував прилеглу до нього версію сховища. Я, можливо, матиму це назад. У будь-якому випадку, включити захист в упакованому заголовку встановлено з підкресленням. (Це може бути умовою для пакетів або, можливо, способом навмисно запобігти змішуванню обох, хоча кваліфікуючі версії мали б для мене більше сенсу.)
Джон П

714

Єдиний спосіб знати - це прочитати документацію вашої реалізації.

У розділі 6.10.2 стандарту C , параграфах 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директиви обробляється так само, як у звичайному тексті. (Кожен ідентифікатор, визначений в даний час як ім'я макросу, замінюється його списком заміни попередніх обробних жетонів.) Директива, що випливає після всіх замін, повинна відповідати одній з двох попередніх форм. Метод, за допомогою якого послідовність попередньої обробки лексем між a <і >парою лексеми попередньої обробки або парою "символів об'єднується в один заголовок попередньої обробки маркера імені, визначений реалізацією.

Визначення:

  • h-char: будь-який член набору вихідних символів, крім символів нового рядка та >

  • q-char: будь-який член набору вихідних символів, крім символів нового рядка та "


108
Доречно: реалізація в g ++ та у візуальному c ++
Олександр Малахов

27
@piCookie шукайте місця, визначені реалізацією, і <ім'я файлу>, і "ім'я файлу". То в чому різниця?
onmyway133

15
@Stefan, я просто цитую стандарт, який нічого не говорить про INCLUDE_PATH. Ваша реалізація може це зробити, а моя не може. Оригінальне запитання було загалом на C, а не конкретно на gcc (що, на мою думку, не використовує INCLUDE_PATH) або Microsoft C (що, на мою думку, є) або будь-яке інше, тому на нього не можна відповісти загально, але натомість на кожну документацію про виконання потрібно посилатися.
piCookie

12
Як і у всіх цих ситуаціях, конкретні приклади (особливо загальних сценаріїв) дуже корисні і однаково оцінені. Зайві тупі загальні відповіді не мають такої практичної користі.
варгонська

132
"Ось як стандарт C може бути багатослівним і не відповідати на ваше запитання"
anatolyg

287

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

Якщо використовується #include "file"форма, реалізація спочатку шукає файл із вказаним іменем, якщо воно підтримується. Якщо ні (підтримується), або якщо пошук не вдається, реалізація поводиться так, ніби інша (#include <file> була використана ) форма.

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


50
+1, це, мабуть, найбільш стисла і правильна відповідь тут. Відповідно до стандарту (з якого цитує piCookie у своїй відповіді), єдиною реальною різницею є "заголовок" проти "вихідний файл". Механізм пошуку визначається в будь-якому випадку. Використання подвійних лапок означає, що ви маєте намір включити "вихідний файл", тоді як кутові дужки означають, що ви маєте намір включити "заголовок", який, як ви кажете, може бути зовсім не файлом.
Dan Molding

3
Дивіться коментар Дена Молдінга до відповіді quest49; стандартні заголовки не повинні бути у формі файлів, вони можуть бути вбудованими.
аїб

10
Я читав це "стандартні заголовки не повинні бути у формі файлів" протягом десяти років. Хочете надати приклад у реальному світі?
Максим Єгорушкін

12
@Maxim Єгорушкін: Я не можу придумати жодних існуючих прикладів у реальному світі; однак, для MS-DOS не може існувати повний компілятор C11, якщо заголовки не повинні бути файлами. Це пояснюється тим, що деякі назви заголовків C11 не сумісні з обмеженням назви файлів MS-DOS "8.3".
Dan Molding

18
@MaximEgorushkin: Компілятор VAX / VMS C зберігав усі заголовки бібліотеки часу виконання C в одному текстовому файлі бібліотеки (подібний до архіву unix) і використовував рядок між <і >як ключ для індексації в бібліотеці.
Адріан Маккарті

117

Деякі хороші відповіді тут посилаються на стандарт C, але забули про стандарт POSIX, особливо про особливості поведінки команди c99 (наприклад, компілятор C) .

Відповідно до Технічної бази відкритої групи, випуск 7 ,

каталог

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

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


1
Яке саме джерело тексту? Це з нормативної частини IEEE Std 1003.1, 2013?
osgx

7
@osgx: таке формулювання (або щось надзвичайно подібне) знайдене в специфікації POSIX для c99- що є назвою POSIX для компілятора C. (Стандарт POSIX 2008 навряд чи може посилатися на C11; оновлення 2013 до POSIX 2008 не змінило стандарт C, про який він посилався.)
Джонатан Леффлер

1
Це теж була моя перша думка. Сторінка для gcc включає це, як і інші. Існує також аналогічна річ для бібліотек - -L.
Прифтан

50

Документація GCC говорить про різницю між ними:

І користувацькі, і файли системних заголовків включаються за допомогою директиви попередньої обробки ‘#include’. Він має два варіанти:

#include <file>

Цей варіант використовується для файлів заголовків системи. Він шукає файл з іменем файлу в стандартному списку системних каталогів. Ви можете додати каталоги до цього списку за допомогою -Iпараметра (див. Виклик ).

#include "file"

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

Однак, якщо нахили нахилу накидаються у файлі, вони вважаються звичайними текстовими символами, а не символами. Жодна послідовність відхилення символів, відповідна константам рядка в С, не обробляється. Таким чином, #include "x\n\\y"вказується ім'я файлу, що містить три зворотні риски. (Деякі системи інтерпретують "\" як роздільник імен траєкторії. Усі вони також трактуються ‘/’однаково. Це найбільш портативний варіант використання ‘/’.)

Це помилка, якщо в рядку після назви файлу є щось (крім коментарів).


46

Це робить:

"mypath/myfile" is short for ./mypath/myfile

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

і

<mypath/myfile> is short for <defaultincludepaths>/mypath/myfile

Якщо ./є <default_include_paths>, то це не має значення.

Якщо mypath/myfileв іншому каталогу включення, поведінка не визначена.


12
Ні, #include "mypath/myfile"не рівнозначно #include "./mypath/myfile". Як йдеться у відповіді piCookie, подвійні лапки говорять компілятору шукати визначений реалізацією спосіб - що включає пошук у місцях, визначених для #include <...>. (Насправді це, мабуть, рівнозначно, але тільки тому, що, наприклад, /usr/include/mypath/myfileможна згадати як /usr/include/./mypath/myfile- принаймні на системах, схожих на Unix.)
Кіт Томпсон,

1
@Keith Thompson: Правильно, я думав про свою скриньку Linux. Очевидно, що це може бути інакше. Хоча на практиці Windows як операційна система, яка не є Posix, також інтерпретує / як роздільник шляхів, і ./ також існує.
Стефан Штайгер

1
після цього опція -L dirpath додає dirpath до defaultincludepaths, на відміну від надання іншого значення .(як зазначено вище). Це має очікуваний наслідок того, що обидва #include "..."і #include <...>шукають у dirpath
Protongun

1
Я вважаю, що ця відповідь є невірною, оскільки це означає, що заголовки, що містяться у подвійних лапках, завжди шукаються в поточному робочому каталозі. Механізм пошуку є більш детальним; ця відповідь неповна. Я не додаю цей коментар, щоб скаржитися чи скуголити, а тому, що система просить мене додати коментар, щоб пояснити, чому я проголосував за цю відповідь.
Карло Вуд

39

<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>форми, якщо файл не знайдено. Решта визначається реалізацією.


4
Чи можете ви надати посилання на те, де в стандарті С -Iвказаний цей бізнес?
juanchopanza

1
Я не бачу посилання на це -I.
juanchopanza

2
Це частина, визначена реалізацією.

27

#include <file.h>повідомляє компілятору шукати заголовок у каталозі "включає", наприклад, для MinGW компілятор шукатиме file.hв 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каталогу вашого компілятора.


22

За стандартом - так, вони різні:

  • Директива щодо попередньої обробки форми

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

    здійснює пошук послідовності місць, визначених реалізацією, для заголовка, визначеного однозначно вказаною послідовністю між роздільниками <та >роздільником, і викликає заміну цієї директиви на весь вміст заголовка. Як визначаються місця або визначається заголовок, визначено реалізацією.

  • Директива щодо попередньої обробки форми

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

    викликає заміну цієї директиви всім вмістом вихідного файлу, ідентифікованим визначеною послідовністю між "роздільниками. Шукається в названому вихідному файлі способом, визначеним реалізацією. Якщо цей пошук не підтримується або пошук не вдається, директива переробляється так, ніби вона читається

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

    з ідентичною послідовністю, що міститься (включаючи >символи, якщо такі є) з оригінальної директиви.

  • Директива щодо попередньої обробки форми

    #include pp-tokens new-line

    (що не відповідає одній з двох попередніх форм) дозволено. Попередня обробка лексем після includeдирективи обробляється так само, як у звичайному тексті. (Кожен ідентифікатор, визначений в даний час як ім'я макросу, замінюється його списком заміни попередніх обробних жетонів.) Директива, що випливає після всіх замін, повинна відповідати одній з двох попередніх форм. Метод, за допомогою якого послідовність попередньої обробки лексем між a <і >парою лексеми попередньої обробки або парою "символів об'єднується в один заголовок попередньої обробки маркера імені, визначений реалізацією.

Визначення:

  • h-char: будь-який член набору вихідних символів, крім символів нового рядка та >

  • q-char: будь-який член набору вихідних символів, крім символів нового рядка та "

Зауважте, що стандарт не вказує жодного зв'язку між визначеними реалізацією способами. Перша форма здійснює пошук одним способом, визначеним реалізацією, а друга - визначеним варіантом реалізації. Стандарт також визначає, що певні файли включають (наприклад,<stdio.h> ).

Формально вам доведеться прочитати посібник для вашого компілятора, однак зазвичай (за традицією) #include "..."форма шукає каталог файлу, в якому #includeспочатку було знайдено, а потім у каталогах, які #include <...>форма шукає (включаючи шлях, наприклад, заголовки системи ).


2
Це здебільшого той самий текст, що і відповідь piCookie від семи років раніше.
Кайл Странд

5
@KyleStrand Це тому, що той самий текст є цитатою відповідного розділу в стандарті - цей текст повинен бути ідентичним. Фактична відповідь - це не той самий текст і дещо інша - хоча я також визнаю, що це буде записано в документації для реалізації, я також зазначу, що існує також традиційний спосіб їх інтерпретації (що більшість чи всі компілятори, яких я використовував) .
злетіння

2
IMO це найкраща відповідь тут, оскільки він охоплює як те, що говорить стандарт, так і те, що насправді робить більшість компіляторів.
підключення

17

Дякую за чудові відповіді, esp. Адам Стельмащик і piCookie, і aib.

Як і багато програмістів, я використав неофіційну угоду про використання "myApp.hpp"форми для файлів конкретних додатків та <libHeader.hpp>форму для системних файлів бібліотеки та компілятора, тобто файлів, зазначених у /IтаINCLUDE змінну середовища, в протягом багатьох років , думаючи , що був стандарт.

Однак стандарт C зазначає, що порядок пошуку є специфічним для реалізації, що може ускладнити переносимість. Щоб зробити це гірше, ми використовуємо варення, яке автоматично визначає, де містяться файли. Ви можете використовувати відносні або абсолютні шляхи для файлів, що включають. тобто

#include "../../MyProgDir/SourceDir1/someFile.hpp"

Старіші версії MSVS вимагали подвійних нахилів (\\), але тепер це не потрібно. Я не знаю, коли це змінилося. Просто використовуйте косої риски для сумісності з 'nix (Windows прийме це).

Якщо ви справді переживаєте про це, використовуйте"./myHeader.h" для файлу включення в тому самому каталозі, що і вихідний код (у мого поточного дуже великого проекту є кілька дублікатів, які містять імена файлів, розкидані навколо - справді проблема управління конфігурацією).

Ось пояснення MSDN, скопійоване тут для вашої зручності).

Цитована форма

Препроцесор здійснює пошук файлів, що включають у цьому порядку:

  1. У тому самому каталозі, що і файл, що містить оператор #include.
  2. У каталогах відкритого в даний час включають файли, у зворотному порядку, в якому
    вони були відкриті. Пошук починається в каталозі батьківського файлу включення та
    продовжується вгору через каталоги будь-яких бабусь і дідусів, що включають файли.
  3. Уздовж шляху, визначеного кожним /Iваріантом компілятора.
  4. Уздовж шляхів, які задаються INCLUDEзмінною середовища.

Кутово-кронштейна форма

Препроцесор здійснює пошук файлів, що включають у цьому порядку:

  1. Уздовж шляху, визначеного кожним /Iваріантом компілятора.
  2. Коли компіляція відбувається в командному рядку, уздовж шляхів, які задаються INCLUDEзмінною середовища.

16

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

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

(Див. Http://gcc.gnu.org/onlinedocs/cpp/Invocation.html )


1
Так - існує кілька різних способів породження залежностей. Це одна з них, але це не єдина.
Прифтан

15

Для #include ""компілятора звичайно шукає папку файлу , який містить , які включають і потім інші папки. Для #include <>компілятора не шукайте папку поточного файлу.


1
Не впевнений, чому люди не згодні.
Максим Єгорушкін

Я підозрюю, що це тому, що більшість людей компілюють лише файли у своєму CWD. Якщо ви перебуваєте в foo каталогу, і ви збираєте foo / unittest / bar.c, і він включає bar.h, тоді "bar.h" працює, а <bar.h> - ні.

1
@Maxim люди не згодні, тому що поведінка, яку ви описуєте, не є стандартною С.
osvein

2
@Spookbuster Правильно, стандарт говорить і те, <filename>і "filename"пошук місць, визначених реалізацією.
Максим Єгорушкін

14

Коли ви використовуєте #include <ім'я файла>, попередній процесор шукає файл у каталозі файлів заголовків C \ C ++ (stdio.h \ cstdio, рядок, вектор тощо). Але, коли ви використовуєте #include "ім'я файлу": по-перше, попередній процесор шукає файл у поточному каталозі, а якщо його тут немає - він шукає його в каталозі файлів заголовків C \ C ++.


1
Після того, як ідеальні відповіді були доступні роками, навіщо подавати її, це просто наче неправильно? Незважаючи на те, що загальноприйнята, ця #includeдиректива зовсім не суворо пов'язана з файлами.
ІІнеочікуваний

@IInspectable, будь ласка, поясніть, чому це взагалі не пов’язано з файлами.
Behrooz Karjoo

11

#Include з кутовими дужками буде шукати "залежний від реалізації список місць" (що є дуже складним способом сказати "системні заголовки") для включення файлу.

#Include з цитатами буде просто шукати файл (і, "залежно від реалізації", bleh). Це означає, що в звичайній англійській мові вона намагатиметься застосувати шлях / ім’я файлу, який ви кидаєте на нього, і не буде передбачати системний шлях або підробляти його в іншому випадку.

Крім того, якщо #include "" не вдається, воно перечитується як #include <> за стандартом.

Документація gcc містить (специфічний для компілятора) опис, який хоча і є специфічним для gcc, а не стандартом, але набагато простіше зрозуміти, ніж розмова в стилі адвоката про стандарти ISO.


Однак використання кутових дужок чи лапок не впливає на те, як включаються файли, це абсолютно те саме: препроцесор по суті створює великий вихідний файл, копіюючи код, вставляючи код із файлів, що включають вихідний файл, до надання це до компілятора (препроцесор робить інше, як #define sustitution, #if оцінка тощо), але обробка #include така проста)
Loghorn

А як щодо конфліктів? Наприклад, скажіть, що у мене є zlib.hшляхи пошуку в моєму "користувачеві", а в шляху пошуку системи існує інша версія, то чи #include <zlib.h>включає версію системи та чи #include "zlib.h"мою власну?
the_mandrill

Ага, відповів на мій власний питання: stackoverflow.com/questions/21593 / ...
the_mandrill

Дякуємо вам за те, що визнали, що і стандарт (и), і типові умови реалізації тут є релевантними, а не просто заявляють, що вони непізнавальні, оскільки це не визначено стандартом.
Кайл Странд

10
#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
  • #include <> призначений для попередньо визначених файлів заголовків

Якщо файл заголовка заздалегідь визначений, ви просто напишіть ім'я файлу заголовка у кутових дужках, і це виглядатиме так (припускаючи, що у нас є попередньо визначене ім'я файлу заголовка iostream):

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

Якщо ви (програміст) написали свій власний файл заголовка, то ви б написали ім'я файла заголовка в лапки. Отже, припустимо, що ви написали заголовок, який називається myfile.h, тоді це приклад того, як ви використовуєте директиву include для включення цього файлу:

#include "myfile.h"

2
Це взагалі не має нічого спільного з попередньо визначеними файлами заголовків. Це стосується місць пошуку.
C Джонсон

9

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

Це не чисто гіпотетично. Є принаймні один компілятор, який працює таким чином. #include <xxx>Рекомендується використовувати лише зі стандартними заголовками.


9
#include <abc.h>

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

#include "xyz.h"

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


7

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

Перший - #include, який вказує препроцесору шукати файл у заздалегідь заданому місці за замовчуванням. Це місце часто є змінною середовища INCLUDE, яка позначає шлях до включення файлів.

Другий тип - це #include "ім'я файлу", яке спонукає препроцесора спочатку шукати файл у поточному каталозі, а потім шукати його у визначених для цього місцях.


7

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

По-перше, шукає наявність файлу заголовка в поточному каталозі, звідки викликається директива. Якщо його не знайдено, він здійснює пошук у попередньо налаштованому списку стандартних системних каталогів.

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

Це шукає наявність файлу заголовка в поточному каталозі, звідки виводиться директива.


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

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


В основному форма "xxx" - це не що інше, як пошук у поточному каталозі; якщо його не знайшли, повертаючи форму


3
Якщо ви вирішите відповісти на старіші запитання, на які є чітко встановлені та правильні відповіді, додавання нової відповіді в кінці дня може не отримати вам жодної заслуги. Якщо у вас є якась нова відмінна інформація, або ви впевнені, що інші відповіді невірні, будь-ласка, додайте нову відповідь, але "ще одна відповідь", що дає ту саму основну інформацію довгий час після того, як запитання, як правило, вигравали " t заробляєш багато кредиту.
Джонатан Леффлер

1
@ Джонатан Леффлер Чи можете ви вказати мені на "добре встановлену" відповідь, яку ви вважаєте такою ж стислою і точною, як відповідь Даршана?
personal_cloud

1
Опис #include "header.h"форми не точний, @personal_cloud. Я вважаю, що відповідь piCookie та Yann Droneaud є найбільш актуальною, оскільки вони визначають, звідки береться їх інформація. Я також не вважаю, що відповідь, який голосує на вершині голосів, є цілком задовільним.
Джонатан Леффлер

Чому ця відповідь відображається вгорі, тоді як дві відповіді далі внизу є 650+ голосів? Ця відповідь збентежила мене, оскільки вона не відповідає поведінці, яку я спостерігав. Це може бути, тому що останнє речення порушено через не уникнення кутових дужок. Я не впевнений, що це має означати.
Неоніт

6

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


6

"<ім'я файлу>" здійснює пошук у стандартних місцях бібліотеки С

тоді як "ім'я файлу" здійснює пошук і в поточному каталозі.

В ідеалі, ви б використовували <...> для стандартних бібліотек C і "..." для бібліотек, які ви пишете і які присутні у поточному каталозі.


4
Яка нова інформація додає цю відповідь до інших?
Даніель Лангр

5

Просте загальне правило - використовувати кутові дужки для включення файлів заголовків, що постачаються разом із компілятором. Використовуйте подвійні лапки, щоб включити будь-які інші файли заголовків. Більшість компіляторів роблять це так.

1.9 - Файли заголовків пояснюють більш докладно про директиви перед процесором. Якщо ви початківець програміст, ця сторінка повинна допомогти вам зрозуміти все це. Я дізнався це звідси, і за цим слідкував за роботою.


4
#include <filename>

використовується, коли потрібно використовувати файл заголовка системи C / C ++ або бібліотеки компілятора. Ці бібліотеки можуть бути stdio.h, string.h, math.h тощо.

#include "path-to-file/filename"

використовується, коли ви хочете використовувати власний власний файл заголовка, який знаходиться у папці вашого проекту чи десь ще.

Для отримання додаткової інформації про препроцесори та заголовки. Читайте С - попередники .


3

#include <filename>

  • Препроцесор здійснює пошук в залежності від реалізації способом. Він повідомляє компілятору шукати каталог, де зберігаються файли заголовків системи.
  • Цей метод зазвичай використовують для пошуку стандартних файлів заголовків.

#include "filename"

  • Це повідомити компілятор для пошуку файлів заголовків, де працює програма. Якщо це не вдалося, поводьте себе так#include <filename> та шукайте цей заголовок у місці, де зберігаються файли заголовків системи.
  • Цей метод зазвичай використовується для ідентифікації визначених користувачем файлів заголовків (файли заголовків, які створюються користувачем). Там не використовуйте це, якщо ви хочете зателефонувати у стандартну бібліотеку, оскільки це займає більше часу на збирання, ніж #include <filename>.

2

Щоб побачити порядок пошуку у вашій системі за допомогою 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 InstalledDir: Бібліотека / Розробник / CommandLineTools / usr / bin
"/ Бібліотека / Розробник / CommandLineTools / usr / bin / clang" -cc1-трипл x86_64-apple-macosx10.14.0 -Wdeprecated-objc-isa-use -Werror = deprected-objc-isa-use -E -disable-free - enable-llvm-verifier -discard-value-names -main-file-name null -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -fno-строгий-return -masm-verbose - munwind-table-target-cpu penryn -warf-column-info -debugger-tuning = lldb -target-linker-версія 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-extension-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" ігнорування неіснуючого каталог "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/Library/Frameworks"
#include "..." пошук починається тут:
#include <...> пошук починається тут:
/ usr / local / include
/ Бібліотека / розробник / CommandLineTools / usr / lib / clang / 10.0.0 / включати
/ Бібліотека / розробник / CommandLineTools / usr / включати
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include
/ Library / Developer / CommandLineTools / SDK / MacOSX10.14.sdk / Система / Бібліотека / Рамки (рамковий каталог)
Кінець списку пошуку.


1
#include <file> 

Включає файл, де знаходиться каталог за замовчуванням.

#include "file" 

Включає файл у поточний каталог, в який він був складений.


-2

Існує два способи написання #include заяви. Це:

#include"filename"
#include<filename>

Сенс кожної форми є

#include"mylib.h"

Ця команда шукатиме файл mylib.hу поточному каталозі, а також вказаний список каталогів, як згадувалося n, включаючи шлях пошуку, який, можливо, був налаштований.

#include<mylib.h>

Ця команда шукатиме файл лише mylib.hу вказаному списку каталогів.

Шлях пошуку включити - це не що інше, як список каталогів, в яких можна було б шукати файл, який включається. Різні компілятори C дозволяють вам задати шлях пошуку різними способами.


1
Якщо ви вирішите відповісти на старіші запитання, на які є чітко встановлені та правильні відповіді, додавання нової відповіді в кінці дня може не отримати вам жодної заслуги. Якщо у вас є якась нова відмінна інформація, або ви впевнені, що інші відповіді невірні, будь-ласка, додайте нову відповідь, але "ще одна відповідь", що дає ту саму основну інформацію довгий час після того, як запитання, як правило, вигравали " t заробляєш багато кредиту.
Джонатан Леффлер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.