Jaka jest różnica w stosowaniu nawiasów kątowych i cudzysłowach w include
instrukcjach w językach programowania C i C ++ ?
#include <filename>
#include "filename"
c++
c
include
header-files
c-preprocessor
quest49
źródło
źródło
Odpowiedzi:
W praktyce różnica polega na lokalizacji, w której preprocesor szuka dołączonego pliku.
W
#include <filename>
przypadku wyszukiwania preprocesora w sposób zależny od implementacji, zwykle w katalogach wyszukiwania wstępnie wyznaczonych przez kompilator / IDE. Ta metoda jest zwykle stosowana do dołączania standardowych plików nagłówkowych bibliotek.Dla
#include "filename"
wyszukiwań preprocesora pierwszych w tym samym katalogu co plik zawierający dyrektywę, a następnie podąża ścieżką przeszukiwania używana do#include <filename>
formularza. Ta metoda jest zwykle stosowana do dołączania plików nagłówkowych zdefiniowanych przez programistę.Pełniejszy opis znajduje się w dokumentacji GCC na temat ścieżek wyszukiwania .
źródło
#include <...>
użyłem pakietu zainstalowanego w systemie i#include "..."
użyłem pobliskiej wersji repozytorium. Mogę mieć to do tyłu. Tak czy inaczej, osłona włączająca w spakowanym nagłówku jest poprzedzona znakiem podkreślenia. (Może to być konwencja dla pakietów lub może sposób celowego zapobiegania mieszaniu się tych dwóch, chociaż kwalifikatory wersji miałyby dla mnie większy sens).Jedynym sposobem na poznanie jest przeczytanie dokumentacji implementacji.
W normie C sekcja 6.10.2 pkt 2–4 stanowi:
źródło
Sekwencja znaków między <i> jednoznacznie odnosi się do nagłówka, który niekoniecznie musi być plikiem. Implementacje są w zasadzie dowolne w użyciu sekwencji znaków, jak chcą. (Przeważnie jednak po prostu traktuj to jako nazwę pliku i przeszukaj ścieżkę dołączania , tak jak podają inne posty).
Jeśli
#include "file"
formularz jest używany, implementacja najpierw szuka pliku o podanej nazwie, jeśli jest obsługiwany. Jeśli nie (obsługiwane) lub jeśli wyszukiwanie się nie powiedzie, implementacja zachowuje się tak, jakby#include <file>
użyto innej ( ) formy.Istnieje również trzeci formularz, który jest używany, gdy
#include
dyrektywa nie pasuje do żadnego z powyższych formularzy. W tej formie niektóre podstawowe przetwarzanie wstępne (takie jak rozwijanie makr) odbywa się na „operandach”#include
dyrektywy, a wynik powinien być zgodny z jedną z dwóch pozostałych postaci.źródło
<
oraz>
jako klucza do indeksowania w bibliotece.Niektóre dobre odpowiedzi tutaj odnoszą się do standardu C, ale zapomniały o standardzie POSIX, szczególnie specyficzne zachowanie polecenia c99 (np. Kompilatora C) .
Zgodnie z The Open Group Base Specification Issue 7 ,
Tak więc, w środowisku zgodnym z POSIX, z kompilatorem C zgodnym z POSIX,
#include "file.h"
prawdopodobnie./file.h
najpierw szuka , gdzie.
jest katalog, w którym znajduje się plik z#include
instrukcją, a#include <file.h>
prawdopodobnie/usr/include/file.h
najpierw szuka , gdzie/usr/include
jest zdefiniowany system zwykłe miejsca na nagłówki (wydaje się, że nie jest zdefiniowane przez POSIX).źródło
c99
- która jest nazwą POSIX dla kompilatora C. (Standard POSIX 2008 z trudem mógł odnosić się do C11; aktualizacja POSIX 2008 z 2013 r. Nie zmieniła standardu C, do którego się odwoływał).-L
.Dokumentacja GCC mówi o różnicy między nimi:
źródło
To robi:
gdzie
.
jest katalogiem pliku, w którym#include
jest on zawarty, i / lub bieżącym katalogiem roboczym kompilatora i / lubdefault_include_paths
i
Jeśli
./
jest włączony<default_include_paths>
, to nie ma znaczenia.Jeśli
mypath/myfile
znajduje się w innym katalogu dołączania, zachowanie jest niezdefiniowane.źródło
#include "mypath/myfile"
nie jest równoważne z#include "./mypath/myfile"
. Jak mówi odpowiedź piCookie, podwójne cudzysłowy nakazują kompilatorowi wyszukiwanie w sposób zdefiniowany w implementacji - co obejmuje wyszukiwanie w określonych miejscach#include <...>
. (W rzeczywistości jest to prawdopodobnie równoważne, ale tylko dlatego, że na przykład/usr/include/mypath/myfile
można go określić jako/usr/include/./mypath/myfile
- przynajmniej w systemach uniksopodobnych).defaultincludepaths
, w przeciwieństwie do nadawania innego znaczenia.
(jak wspomniano powyżej). Ma to oczekiwaną konsekwencję, że zarówno#include "..."
i#include <...>
poszukiwania w dirpathThe
<file>
mówi preprocesorowi, aby najpierw przeszukał-I
katalogi i predefiniowane katalogi , a następnie katalog .c. To mówi preprocesora szukać katalogu plik źródłowy jest pierwszy , a następnie przywrócić i predefiniowane. Wszystkie miejsca docelowe są przeszukiwane, tylko kolejność wyszukiwania jest inna."file"
-I
Standard z 2011 r. Omawia głównie pliki dołączane w „Uwzględnieniu plików źródłowych 16,2”.
Zauważ, że
"xxx"
forma obniża się do<xxx>
formy, jeśli plik nie zostanie znaleziony. Reszta jest zdefiniowana w implementacji.źródło
-I
firmę?-I
.#include <file.h>
mówi kompilatorowi, aby szukał nagłówka w swoim katalogu „obejmuje”, np. w przypadku MinGW kompilator szukafile.h
w C: \ MinGW \ include \ lub gdziekolwiek jest zainstalowany kompilator.#include "file"
każe kompilatorowi przeszukać bieżący katalog (tj. katalog, w którym znajduje się plik źródłowy)file
.Możesz użyć
-I
flagi dla GCC, aby powiedzieć jej, że gdy napotka inkluzję z nawiasami kątowymi, powinna również wyszukać nagłówki w katalogu po-I
. GCC będzie traktować katalog po fladze tak, jakby byłincludes
katalogiem.Na przykład, jeśli masz plik wywoływany
myheader.h
we własnym katalogu, możesz powiedzieć,#include <myheader.h>
czy zadzwoniłeś do GCC z flagą-I .
(wskazując, że powinien on szukać zawiera w bieżącym katalogu).Bez
-I
flagi będziesz musiał użyć,#include "myheader.h"
aby dołączyć plik lub przejśćmyheader.h
doinclude
katalogu kompilatora.źródło
Standardowo - tak, są różne:
Należy zauważyć, że standard nie określa żadnego związku między sposobami zdefiniowanymi w implementacji. Pierwsza forma wyszukuje w jeden sposób zdefiniowany przez implementację, a drugi w (ewentualnie inny) sposób zdefiniowany przez implementację. Standard określa również, że niektóre pliki dołączane powinny być obecne (na przykład
<stdio.h>
).Formalnie trzeba przeczytać instrukcję kompilatora, jednak zwykle (zgodnie z tradycją)
#include "..."
formularz przeszukuje katalog pliku, w którym#include
najpierw został znaleziony, a następnie katalogi, które#include <...>
przeszukuje formularz (zawiera ścieżkę, np. Nagłówki systemowe ).źródło
Dzięki za wspaniałe odpowiedzi, szczególnie. Adam Stelmaszczyk i piCookie oraz aib.
Podobnie jak wielu programistów, Użyłem nieformalna konwencja pomocą
"myApp.hpp"
formularza do konkretnych zastosowań plików, oraz<libHeader.hpp>
formularz do plików bibliotek systemowych i kompilator, czyli pliki określone w/I
aINCLUDE
zmienną środowiskową przez lata myślenia, która była średnia.Jednak standard C mówi, że kolejność wyszukiwania jest specyficzna dla implementacji, co może utrudnić przenoszenie. Co gorsza, używamy jam, który automatycznie rozpoznaje, gdzie znajdują się pliki dołączeń. Możesz użyć względnych lub bezwzględnych ścieżek dla plików dołączanych. to znaczy
Starsze wersje MSVS wymagały podwójnych ukośników odwrotnych (\\), ale teraz nie jest to wymagane. Nie wiem kiedy to się zmieniło. Wystarczy użyć ukośników, aby zachować zgodność z 'nix (Windows to zaakceptuje).
Jeśli naprawdę się o to martwisz, użyj
"./myHeader.h"
pliku dołączenia w tym samym katalogu co kod źródłowy (w moim obecnym, bardzo dużym projekcie są rozproszone zduplikowane nazwy plików dołączonych - to naprawdę problem z zarządzaniem konfiguracją).Oto wyjaśnienie MSDN skopiowane tutaj dla Twojej wygody).
źródło
Przynajmniej dla wersji GCC <= 3.0 forma nawiasu kątowego nie generuje zależności między dołączonym plikiem a plikiem zawierającym.
Więc jeśli chcesz wygenerować reguły zależności (na przykład przy użyciu opcji GCC -M), musisz użyć cytowanego formularza dla plików, które powinny zostać uwzględnione w drzewie zależności.
(Zobacz http://gcc.gnu.org/onlinedocs/cpp/Invocation.html )
źródło
Dla
#include ""
kompilatora zwykle przeszukuje folder pliku zawierającego że to i wtedy inne foldery. Dla#include <>
kompilatora nie wyszukuje folderu bieżącego pliku.źródło
<filename>
i"filename"
szuka miejsc zdefiniowanych w implementacji.Gdy używasz #include <nazwa_pliku>, procesor wstępny szuka pliku w katalogu plików nagłówkowych C \ C ++ (stdio.h \ cstdio, łańcuch, wektor itp.). Ale kiedy użyjesz #include "nazwa_pliku": po pierwsze, procesor wstępny szuka pliku w bieżącym katalogu, a jeśli go nie ma - szuka go w katalogu plików nagłówkowych C \ C ++.
źródło
#include
dyrektywa wcale nie jest ściśle związana z plikami.#Include z nawiasami kątowymi przeszuka „zależną od implementacji listę miejsc” (co jest bardzo skomplikowanym sposobem powiedzenia „nagłówków systemowych”) w celu dołączenia pliku.
#Include z cytatami po prostu wyszuka plik (i „w sposób zależny od implementacji”, bleh). Co oznacza, że w normalnym języku angielskim spróbuje zastosować ścieżkę / nazwę pliku, którą rzucisz na nią, i nie będzie poprzedzać ścieżki systemowej ani w żaden inny sposób nią manipulować.
Ponadto, jeśli #include "" zawiedzie, jest on ponownie odczytywany jako #include <> przez standard.
The gcc ma (specyficzny dla kompilatora) opis, który chociaż jest specyficzny dla gcc, a nie standardu, jest o wiele łatwiejszy do zrozumienia niż rozmowa o standardach ISO w stylu adwokata.
źródło
zlib.h
na ścieżkach wyszukiwania „użytkownik”, a inna ścieżka istnieje w ścieżce wyszukiwania systemu, a następnie#include <zlib.h>
obejmuje wersję systemu i#include "zlib.h"
własną?Przykład:
Nazwa pliku tutaj to
Seller.h
:W implementacji klasy (na przykład
Seller.cpp
oraz w innych plikach, które będą korzystały z tego plikuSeller.h
), nagłówek zdefiniowany przez użytkownika powinien teraz zostać uwzględniony w następujący sposób:źródło
#include <>
jest dla predefiniowanych plików nagłówkowychJeśli plik nagłówka jest predefiniowany, wystarczy wpisać nazwę pliku nagłówka w nawiasach kwadratowych i wyglądałby tak (zakładając, że mamy wstępnie zdefiniowaną nazwę pliku nagłówka iostream):
#include " "
jest dla plików nagłówkowych definiowanych przez programistęJeśli ty (programista) napisałeś swój własny plik nagłówka, wówczas zapisałbyś nazwę pliku nagłówka w cudzysłowie. Załóżmy, że napisałeś plik nagłówka o nazwie
myfile.h
, to jest przykład użycia dyrektywy include w celu włączenia tego pliku:źródło
Wiele odpowiedzi tutaj koncentruje się na ścieżkach, które kompilator będzie szukał w celu znalezienia pliku. Podczas gdy to właśnie robi większość kompilatorów, zgodny kompilator może być wstępnie zaprogramowany z efektami standardowych nagłówków i traktować, powiedzmy,
#include <list>
jako przełącznik, i wcale nie musi istnieć jako plik.To nie jest czysto hipotetyczne. W ten sposób działa co najmniej jeden kompilator.
#include <xxx>
Zalecane jest używanie tylko ze standardowymi nagłówkami.źródło
służy do dołączania standardowych plików bibliotecznych. Kompilator sprawdzi zatem, gdzie znajdują się standardowe nagłówki bibliotek.
powie kompilatorowi, aby uwzględnił pliki nagłówkowe zdefiniowane przez użytkownika. Tak więc kompilator sprawdzi, czy te pliki nagłówkowe znajdują się w bieżącym folderze lub
-I
zdefiniowanych folderach.źródło
W C ++ dołącz plik na dwa sposoby:
Pierwszym jest #include, który mówi preprocesorowi, aby szukał pliku w predefiniowanej domyślnej lokalizacji. Ta lokalizacja jest często zmienną środowiskową INCLUDE, która wskazuje ścieżkę do dołączenia plików.
Drugi typ to #include „nazwa_pliku”, który mówi preprocesorowi, aby najpierw szukał pliku w bieżącym katalogu, a następnie szukał go w predefiniowanych lokalizacjach, które skonfigurował użytkownik.
źródło
Formularz 1 - #include <xxx>
Najpierw sprawdza obecność pliku nagłówkowego w bieżącym katalogu, z którego wywoływana jest dyrektywa. Jeśli nie zostanie znaleziony, przeszukuje wstępnie skonfigurowaną listę standardowych katalogów systemowych.
Formularz 2 - #include „xxx”
Wyszukuje obecność pliku nagłówka w bieżącym katalogu, z którego wywoływana jest dyrektywa.
Dokładna lista katalogów wyszukiwania zależy od systemu docelowego, konfiguracji GCC i miejsca instalacji. Możesz znaleźć listę katalogów wyszukiwania swojego kompilatora GCC, uruchamiając go z opcją -v.
Możesz dodać dodatkowe katalogi do ścieżki wyszukiwania, używając - I dir , co powoduje, że dir jest przeszukiwany po bieżącym katalogu (w formie wyceny dyrektywy) i przed standardowymi katalogami systemowymi.
Zasadniczo forma „xxx” jest niczym innym jak wyszukiwaniem w bieżącym katalogu; jeśli nie zostanie znalezione przewrócenie formularza
źródło
#include "header.h"
formularza jest niedokładny, @personal_cloud. Uważam, że odpowiedź piCookie i Yanna Droneauda jest najistotniejsza, ponieważ wskazują, skąd pochodzą ich informacje. Nie wydaje mi się też, aby najlepiej głosowana odpowiedź była w pełni satysfakcjonująca.#include <filename>
Jest używany, gdy system plików jest mowa. Jest to plik nagłówkowy, który można znaleźć w domyślnych lokalizacjach systemu, takich jak/usr/include
lub/usr/local/include
. W przypadku własnych plików, które muszą być zawarte w innym programie, musisz użyć#include "filename"
składni.źródło
Idealnie byłoby użyć <...> dla standardowych bibliotek C i „...” dla bibliotek, które piszesz i są obecne w bieżącym katalogu.
źródło
Prostą ogólną zasadą jest stosowanie nawiasów kątowych do dołączania plików nagłówkowych dostarczanych z kompilatorem. Użyj cudzysłowów, aby dołączyć inne pliki nagłówkowe. Większość kompilatorów robi to w ten sposób.
1.9 - Pliki nagłówkowe wyjaśniają bardziej szczegółowo dyrektywy poprzedzające procesor. Jeśli jesteś początkującym programistą, ta strona powinna pomóc Ci to wszystko zrozumieć. Nauczyłem się tego stąd i śledziłem to w pracy.
źródło
#include <filename>
jest używany, gdy chcesz użyć pliku nagłówka systemu C / C ++ lub bibliotek kompilatora. Bibliotekami tymi mogą być stdio.h, string.h, matematyka.h itp.
#include "path-to-file/filename"
jest używany, gdy chcesz użyć własnego niestandardowego pliku nagłówka, który znajduje się w folderze projektu lub w innym miejscu.
Aby uzyskać więcej informacji na temat preprocesorów i nagłówka. Czytaj C - Preprocesory .
źródło
#include <filename>
#include "filename"
#include <filename>
i przeszukuje ten plik nagłówka w miejscu, w którym przechowywane są pliki nagłówka systemowego.#include <filename>
.źródło
Aby zobaczyć kolejność wyszukiwania w systemie za pomocą gcc, w oparciu o bieżącą konfigurację, możesz wykonać następujące polecenie. Więcej informacji na temat tego polecenia można znaleźć tutaj
cpp -v /dev/null -o /dev/null
źródło
Zawiera plik, w którym domyślny jest katalog włączania.
Zawiera plik w bieżącym katalogu, w którym został skompilowany.
źródło
Istnieją dwa sposoby napisania instrukcji #include. Są to:
Znaczenie każdej formy to
To polecenie szuka pliku
mylib.h
w bieżącym katalogu, a także podanej listy katalogów, jak wspomniano w ścieżce wyszukiwania dołączania, która mogła zostać skonfigurowana.To polecenie szuka pliku tylko
mylib.h
na określonej liście katalogów.Ścieżka wyszukiwania dołączania to nic innego jak lista katalogów, które będą wyszukiwane w poszukiwaniu dołączanego pliku. Różne kompilatory C pozwalają ustawić ścieżkę wyszukiwania na różne sposoby.
źródło