Koja je razlika između #include <filename> i #include "filename"?

U programskim jezicima C i C ++, koja je razlika između upotrebe kutnih zagrada i korištenja navodnika u include izjavi kako slijedi?

  • #include <filename>
  • #include "filename"
1937
22 авг. set quest49 22 kol. 2008-08-22 04:40 '08 u 4:40 2008-08-22 04:40
@ 32 odgovora
  • 1
  • 2

U praksi, razlika je u tome što pretprocesor traži uključenu datoteku.

Za #include <filename> predprocesor obavlja pretraživanje na temelju implementacije, obično u direktorijima za pretraživanje koje je prethodno dodijelio prevodilac / IDE. Ova metoda se obično koristi za uključivanje datoteka zaglavlja standardne knjižnice.

Za #include "filename" pretprocesor izgleda najprije u istom direktoriju kao i datoteka koja sadrži direktivu, a zatim slijedi put pretraživanja koji se koristi za obrazac #include <filename> . Ova metoda se obično koristi za uključivanje datoteka zaglavlja koje definira programer.

Potpuniji opis dostupan je u GCC dokumentaciji na putu pretraživanja .

1127
22 авг. odgovor je dat quest49 22 aug. 2008-08-22 04:40 '08 u 4:40 2008-08-22 04:40

Jedini način da saznate jest pročitati dokumentaciju o implementaciji.

Standard C , odjeljak 6.10.2, klauzule 2-4 navodi:

border=0
  • Direktiva o predobradi obrasca

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

    traži niz mjesta definiranih implementacijom za zaglavlje koje je jedinstveno identificirano navedenim redoslijedom između razdjelnika < i > , i uzrokuje da se ta direktiva zamijeni svim sadržajem zaglavlja . Način određivanja mjesta ili određivanja naslova određuje se provedbom.

  • Direktiva o predobradi obrasca

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

    uzrokuje da se ova direktiva zamijeni cijelim sadržajem izvorne datoteke, identificiranom navedenim redoslijedom između razdjelnika. Ime izvorne datoteke se traži u metodi definiranoj implementacijom. Ako ovo pretraživanje nije podržano ili ako pretraživanje ne uspije, direktiva se obrađuje kao da se čita.

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

    s identičnim sadržanim redoslijedom (uključujući > znakove, ako ih ima) iz izvorne direktive.

  • Direktiva o predobradi

     #include pp-tokens new-line 

    (koja ne odgovara jednom od dva prethodna obrasca). Predobrada tokena nakon include u direktivu obrađuje se na isti način kao u običnom tekstu. (Svaki identifikator koji je trenutno definiran kao ime makroa zamjenjuje se popisom popisa za predobradu tokenova.) Direktiva koja proizlazi iz svih zamjena mora odgovarati jednom od dva prethodna obrasca. Metoda kojom se slijed markera za pretprocesiranje između < i > i pretprocesnih markera para ili para znakova kombinira u jedno ime zaglavlja markera predprocesiranja ovisi o implementaciji.

definicije:

  • h-char: bilo koji element izvornog skupa znakova osim znaka za novi redak i >

  • q-char: bilo koji element izvornog skupa znakova osim znaka za novi red i

622
17 сент. Odgovor je dat piCookie 17 sep . 2008-09-17 00:06 '08 u 0:06 2008-09-17 00:06

Redoslijed znakova između <i> jedinstveno se odnosi na zaglavlje, koje nije nužno datoteka. Implementacije su uglavnom slobodne za korištenje niza znakova koje smatrate prikladnim. (Uglavnom, međutim, jednostavno ga tretirajte kao naziv datoteke i potražite uključenu putanju, od ostatka stanja poruke.)

Ako se koristi oblik #include "file" , implementacija najprije traži datoteku s navedenim nazivom, ako je podržana. Ako nije (podržano) ili ako pretraživanje nije izvršeno, implementacija se ponaša kao da je korišten drugi oblik ( #include <file> ).

Osim toga, tu je i treći oblik koji se koristi kada se direktiva #include ne podudara s bilo kojim od gore navedenih obrazaca. U ovom se obliku izvodi neka osnovna predobrada (na primjer, ekspanzija makroa) u operandima direktive #include , a rezultat se očekuje da odgovara jednom od druga dva oblika.

242
08 сент. odgovor dat aib 08 ruj. 2008-09-08 20:43 '08 u 20:43 2008-09-08 20:43

Neki dobri odgovori ovdje sadrže reference na C standard, ali POSIX standard je zaboravljen, posebno specifično ponašanje naredbe c99 (na primjer, C kompilator) .

Prema originalnim specifikacijama Otvorene skupine br .

-I

Izmijenite algoritam pretraživanja za zaglavlja čija imena nisu apsolutni putevi, pogledajte u imenik označen puteljkom imenika, prije nego što pogledate u uobičajena mjesta. Dakle, zaglavlja čija su imena zatvorena u dvostruke navodnike (") prvo se pretražuju u direktoriju datoteke s retkom #include , a zatim u direktorijima nazvanim -I , a posljednji u normalnim mjestima. Za zaglavlja koja imaju imena zatvorena u uglatim zagradama ("<>"), naslov bi se trebao pretraživati ​​samo u direktorijima imenovanim u parametrima -I , a zatim na normalnim mjestima. Katalozi imenovani u parametrima -I trebali bi se naći u navedenom redoslijedu. Implementacije bi trebale podržavati najmanje deset instanci ove opcije u jednom pozivu na naredbu c99.

Dakle, u okruženju kompatibilnom s POSIX-om, s C-kompatibilnim COS prevodiocem, #include "file.h" će najvjerojatnije tražiti ./file.h prvo, gdje . - to je direktorij u kojem se nalazi datoteka s #include #include <file.h> dok #include <file.h> najvjerojatnije traži /usr/include/file.h , gdje je /usr/include vaš sustav mjesta za zaglavlja (ne definira POSIX).

98
20 июля '12 в 12:29 2012-07-20 12:29 odgovor je dao Yann Droneaud 20. srpnja '12 u 12:29 2012-07-20 12:29

On radi:

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

c . je ili direktorij datoteke koja sadrži #include i / ili trenutni radni direktorij prevoditelja i / ili default_include_paths

i

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

Ako je ./ u <default_include_paths> , onda nije važno.

Ako je mypath/myfile u različitom uključenom direktoriju, ponašanje je nedefinirano.

39
08 февр. Odgovor daje Stefan Steiger 08. veljače. 2011-02-08 14:45 '11 u 14:45 2011-02-08 14:45

GCC dokumentacija navodi razliku između njih:

Datoteke s korisničkim i sistemskim zaglavljem su uključene pomoću direktive za predobradu '#include . Ima dvije mogućnosti:

#include <file>

Ova se opcija koristi za datoteke zaglavlja sustava. Pretražuje datoteku s nazivom datoteka u standardnom popisu sistemskih direktorija. Možete dodati direktorije na ovaj popis s opcijama -I (vidi Invocation ).

#include "file"

Ova se opcija koristi za datoteke zaglavlja vašeg programa. Ona traži datoteku pod nazivom datoteka prvo u direktoriju koji sadrži trenutnu datoteku, zatim u direktorijima navodnika, a zatim u istim direktorijima kao za <file> . -Iquote možete dodati na popis direktorija za -Iquote s -Iquote . Argument '#include , razgraničen navodnicima ili kutnim zagradama, ponaša se kao konstanta niza u kojoj se komentari ne prepoznaju, a imena makronaredbi se ne proširuju. Dakle, #include <x/*y> označava uključivanje datoteke zaglavlja sustava pod nazivom x/*y .

Međutim, ako se obrnute kose crte pojavljuju unutar datoteke, one se smatraju znakovima običnog teksta, a ne znakovima za bijeg. Niti jedna od kontrolnih sekvenci znakova koji odgovaraju konstantama niza u C se ne obrađuju, dakle, #include "x\n\\y" označava ime datoteke koja sadrži tri obrnute kose crte. (Neki sustavi tumače 'kao graničnik puta. Također interpretira '/ na isti način.

To je pogreška ako postoji nešto (osim komentara) u retku nakon naziva datoteke.

38
14 янв. Odgovor je dao Suraj Jain 14. siječnja. 2017-01-14 07:52 '17 u 7:52 2017-01-14 07:52

<file> uključuje usmjerava pretprocesoru da traži u direktorijima -I iu unaprijed definiranim direktorijima, a zatim u direktoriju .c datoteku. "file" uključuje predprocesoru da najprije traži direktorij izvorne datoteke, a zatim se vraća na -I i unaprijed je definiran. U svakom slučaju, pretražuju se svi primatelji, samo je redoslijed pretraživanja različit.

2011 standard uglavnom razmatra uključene datoteke u "16.2 Input Source File".

2 Uputite obrazac za predobradu

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

izvršava potragu za nizom mjesta definiranih za implementaciju za zaglavlje, jedinstveno identificira određeni slijed između <i> razdjelnika i poziva zamjenu ove direktive sa svim sadržajem zaglavlja. Kao što je naznačeno mjestom ili označeno naslovom provedbe.

3 Direktiva o predobradi obrasca

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

uzrokuje da se ova direktiva zamijeni cijelim sadržajem izvorne datoteke koja je identificirana navedenim redoslijedom između "razdjelnika". Imenovano pretraživanje izvornih datoteka izvodi se u skladu s implementacijom. Ako ovo pretraživanje nije podržano ili ako pretraživanje nije izvršeno, direktiva se obrađuje kao da se čita

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

s identičnim sadržanim redoslijedom (uključujući> znakove, ako ih ima) iz izvorne direktive.

Imajte na umu da se "xxx" obrazac pogoršava u <xxx> oblik ako datoteka nije pronađena. Ostatak se određuje provedbom.

27
03 сент. odgovor je dat Arkadiy 03 sep. 2008-09-03 15:17 '08 u 15:17 2008-09-03 15:17

Po standardu - da, oni su različiti:

  • Direktiva o unaprijediti obrascu

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

    pretražuje slijed lokacija definiranih za zaglavlje, identificiran jedinstveno specificiranim slijedom između < i > razdjelnika, i uzrokuje da se ova direktiva zamijeni cijelim sadržajem zaglavlja. Kao što je naznačeno lokacijom ili identificiranim zaglavljem, određuje se implementacijom.

  • Direktiva o unaprijediti obrascu

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

    uzrokuje da se ova direktiva zamijeni sa svim sadržajem izvorne datoteke identificirane navedenim redoslijedom između razdjelnika " . Nazvana izvorna datoteka izvršava se u metodi pretraživanja. Ako ovo pretraživanje nije podržano ili se pretraživanje ne provodi, direktiva se obrađuje kao da je pročitana

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

    s identičnom sadržanom sekvencom (uključujući znakove > , ako postoje) iz izvorne direktive.

  • Direktiva o unaprijediti obrascu

     #include pp-tokens new-line 

    (što ne odgovara jednom od dva prethodna obrasca). Struje pretprocesiranja nakon include u direktivu obrađuju se na isti način kao u običnom tekstu. (Svaki identifikator koji je trenutačno definiran kao ime makronaredbe zamjenjuje se popisom zamjenskih znakova pretprocesiranja.) Direktiva primljena nakon svih zamjena mora odgovarati jednom od dva prethodna obrasca. Metoda kojom se slijed znakova za predobradu između parova znakova za predobradu < ili parova znakova " kombinira u jedan zaglavlje, token za prethodnu obradu određuje se implementacijom.

definicija:

  • h-char: bilo koji član izvornog skupa znakova osim znaka za novi red i >

  • q-char: bilo koji član izvornog skupa znakova, osim znaka za novi red, i "

Napominjemo da standard ne ukazuje na nikakvu vezu između načina definiranja provedbe. Prvi se oblik izvodi na jedan način, a drugi na (moguće različit) način provedbe. Standard također navodi da neke uključene datoteke moraju biti prisutne (na primjer, <stdio.h> ).

Formalno, morat ćete pročitati priručnik za svoj kompilator, ali obično (po tradiciji) obrazac #include "..." pretražuje direktorij datoteke u kojoj je #include prvi put pronađen, a zatim direktorije u kojima #include <...> pretraživanje oblika (uključujući putanju, na primjer zaglavlja sustava).

18
18 авг. odgovor dati skyking 18 aug. 2015-08-18 09:21 '15 u 9:21 AM 2015-08-18 09:21

Hvala na velikim odgovorima. Adam Stelmashchik i PiKuki ibyb.

Poput mnogih programera, upotrijebio sam neslužbeni dogovor da koristim obrazac "myApp.hpp" za određene aplikacije i obrazac <libHeader.hpp> za datoteke sistemske knjižnice i prevodilac, tj. Datoteke navedene u /I i varijabli okruženja INCLUDE , za mnoge godina misleći da je to standard.

Međutim, standard C navodi da je redoslijed pretraživanja specifičan za implementaciju, što može učiniti kompleksnost prenosivosti. Što je još gore, mi koristimo džem, koji automatski određuje gdje su uključene datoteke. Možete koristiti relativne ili apsolutne staze za uključene datoteke. to jest.

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

Starije verzije MSVS-a zahtijevaju dvostruku kosu crtu ("", ali to više nije potrebno. \ T Ne znam kad se to promijenilo. Samo upotrijebite kose crte za kompatibilnost s nixom (Windows će to prihvatiti).

Ako ste doista zabrinuti zbog toga, upotrijebite "./myHeader.h" za uključenu datoteku u istom direktoriju kao i izvorni kod (moj trenutni, vrlo veliki projekt ima nekoliko duplikata uključenih imena datoteka, koji su stvarno razbacani o upravljanju konfiguracijom) ,

Ovdje je MSDN objašnjenje kopirano ovdje radi vaše udobnosti).

Citirani oblik

Predprocesor traži uključene datoteke sljedećim redoslijedom:

  • U istom direktoriju kao i datoteka koja sadrži operator #include.
  • U direktorijima otvorenih datoteka uključuju se obrnutim redoslijedom u kojem su otvorene. Pretraživanje počinje u direktoriju matične datoteke i
    Nastavlja prikaz direktorija svih djedova i baka, uključujući datoteke.
  • Na putu navedenom u svakoj opciji kompajlera /I .
  • Duž staze koju postavlja varijabla okruženja INCLUDE .

Oblik kutnog nosača

Predprocesor traži uključene datoteke sljedećim redoslijedom:

  • Na putu navedenom u svakoj opciji kompajlera /I .
  • Kada se kompiliraju u naredbenom retku, staze koje određuje varijabla okruženja INCLUDE .
14
15 окт. odgovor dano riderBill 15 list . 2014-10-15 02:51 '14 u 2:51 2014-10-15 02:51

Barem za GCC verziju <= 3.0, oblik kutne zagrade ne stvara odnos između uključene datoteke i one uključene.

Dakle, ako želite generirati pravila ovisnosti (koristeći primjer GCC-a za primjer), trebate koristiti citirani obrazac za datoteke koje bi trebale biti uključene u stablo ovisnosti.

(pogledajte http://gcc.gnu.org/onlinedocs/cpp/Invocation.html )

13
25 окт. Odgovor dao Denis Ros 25. listopada. 2011-10-25 15:35 '11 u 15:35 2011-10-25 15:35

Za #include "" prevodilac obično traži mapu s datotekom koja ga sadrži, a zatim i druge mape. Za #include <> prevodilac ne traži trenutnu mapu s datotekom.

12
08 февр. Odgovor daje Maxim Egorushkin 08. veljače. 2011-02-08 14:45 '11 u 14:45 2011-02-08 14:45

#include <file.h> kaže prevodiocu da traži zaglavlje u svom direktorijumu uključujući, na primjer, za MinGW, kompajler će tražiti file.h u C: MinGW uključuje ili gdje god je vaš kompajler instaliran.

#include "file" kaže kompajleru da traži trenutni direktorij (tj. direktorij koji sadrži izvornu datoteku) za file .

Možete koristiti zastavu -I za GCC da biste prijavili da kada naiđe na uključi s kutnim zagradama, također treba tražiti zaglavlja u direktoriju nakon -I . GCC će uputiti na direktorij iza zastave, kao da je to direktorij.

Na primjer, ako imate myheader.h u svom direktoriju, možete reći #include <myheader.h> ako ste nazvali GCC s #include <myheader.h> -I. (ukazuje na to da treba pretražiti uključivanje u trenutni direktorij.)

Bez zastavice -I morat ćete upotrijebiti #include "myheader.h" da biste uključili datoteku ili premjestili myheader.h u direktorij include vašeg myheader.h .

12
12 марта '18 в 2:06 2018-03-12 02:06 Odgovor je dao Adrian Zhang 12. ožujka 2010. u 2:06 sati 2018-03-12 02:06
  • #include <> je za unaprijed definirane datoteke zaglavlja.

Ako je datoteka zaglavlja unaprijed definirana, samo napišite ime datoteke zaglavlja u uglatim zagradama, i izgledat će ovako (ako imamo unaprijed definirani naziv datoteke zaglavlja iostream):

 #include <iostream> 
  • #include " " za datoteke zaglavlja koje programer definira

Ako ste vi (programer) napisali vlastitu datoteku zaglavlja, morate napisati ime zaglavlja u navodnicima. Pretpostavimo da ste napisali datoteku zaglavlja pod nazivom myfile.h , onda je ovo primjer kako trebate koristiti direktivu include za uključivanje ove datoteke:

 #include "myfile.h" 
11
17 дек. Odgovor je dat MobiDev 17. prosinca. 2012-12-17 10:54 '12 u 10:54 2012-12-17 10:54

Kada koristite #include <filename>, predprocesor pretražuje datoteku u direktoriju datoteka C C ++ (stdio.h cstdio, string, vector, itd.). No, kada koristite #include "filename": prvo, predprocesor traži datoteku u trenutnom direktoriju, a ako to ne učini, pretražuje je u direktoriju C datoteke zaglavlja C ++.

9
12 апр. Odgovor je dao Chayim Friedman 12. travnja 2018-04-12 09:36 '18 u 9:36 , 2018-04-12 09:36

Objekt #include s uglastim zagradama tražit će "popis mjesta ovisnih o implementaciji" (ovo je vrlo kompliciran način izgovaranja "zaglavlja sustava") kako bi se datoteka uključila.

# uključi s navodnicima samo će tražiti datoteku (i, "ovisno o implementaciji", bleh). To znači da će u normalnom engleskom jeziku pokušati upotrijebiti putanju / naziv datoteke koju bacite na nju, i neće dodavati put sustava ili na drugi način ometati.

Osim toga, ako #include "" ne funkcionira, ponovno se čita kao #include <> kao standard.

Gcc dokumentacija ima opis (specifičan za prevodioce), koji je, budući da je specifičan za gcc, a ne standardni, mnogo lakše razumjeti nego u ISO stilu prava.

9
08 февр. Damon 08 feb. 2011-02-08 15:02 '11 u 15:02 2011-02-08 15:02
 #include <abc.h> 

koristi se za uključivanje standardnih datoteka knjižnice. Stoga će prevodilac provjeriti lokacije standardnih zaglavlja knjižnice.

 #include "xyz.h" 

će obavijestiti prevodioca o uključivanju prilagođenih datoteka zaglavlja. Stoga prevodilac provjerava te datoteke zaglavlja u trenutnoj mapi ili -I posebnim mapama.

8
23 янв. Odgovor dao Christy Wald 23. siječnja 2017-01-23 16:36 '17 u 16:36 2017-01-23 16:36

Mnogi odgovori ovdje su usredotočeni na staze koje će prevodilac pretražiti kako bi pronašao datoteku. Dok većina kompilatora to radi, odgovarajućem kompajleru je dopušteno unaprijed programirati efekte standardnih zaglavlja i tretirati, recimo, #include <list> kao prekidač, i uopće ne bi trebao postojati kao datoteka.

To nije čisto hipotetičko. Postoji barem jedan prevodilac koji radi na taj način. Preporučljivo je koristiti #include <xxx> sa standardnim zaglavljem.

8
25 февр. odgovor je dan sp2danny 25. veljače. 2014-02-25 13:49 '14 u 13:49 2014-02-25 13:49
 #include "filename" // User defined header #include <filename> // Standard library header. 

primjer:

Ovdje je naziv datoteke 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" 
8
ответ дан Barbara 28 сент. '11 в 23:37 2011-09-28 23:37