#İnclude <filename> ve #include “filename” arasındaki fark nedir?


Yanıtlar:


1404

Uygulamada, fark ön işlemcinin dahil edilen dosyayı aradığı konumdadır.

İçin #include <filename>normalde arama dizinleri bir uygulama bağımlı bir şekilde önişlemci aramaları, derleyici / IDE tarafından belirlenmiş önceden. Bu yöntem normalde standart kütüphane başlık dosyalarını dahil etmek için kullanılır.

İçin #include "filename"sonra yönergesini içeren ve dosyasıyla aynı dizinde ilk önişlemci aramalar için kullanılan arama yolu izler#include <filename> formu. Bu yöntem normal olarak programcı tanımlı başlık dosyalarını dahil etmek için kullanılır.

Arama yollarıyla ilgili GCC belgelerinde daha eksiksiz bir açıklama mevcuttur .


135
"Önişlemci aynı dizinde arama yapıyor ..." ifadesi pratikte doğru olabilir, ancak standart, belirtilen kaynak dosyanın "uygulama tanımlı bir şekilde arandığını" belirtir. PiCookie'nin cevabına bakınız.
Richard Corden

60
Cevabınız "doğru" gibi görünse de, konvansiyonla kaç uygulama olduğu için aib ve piCookie'nin cevaplarına yakından bakmalısınız. Her ikisi de (C standardının ifadeleri ile desteklenmektedir) gerçek ayrımın bir "kaynak" ile bir "kaynak dosyasının" dahil edilmesine (ve hayır, bunun ".h" vs. "anlamına gelmediğine işaret eder). c "). Bu bağlamdaki "kaynak dosya" bir ".h" dosyası olabilir (ve genellikle her zaman olur ve olmalıdır). Bir başlığın bir dosya olması gerekmez (bir derleyici, örneğin bir dosyada değil, statik olarak kodlanmış bir başlık içerebilir).
Dan Moulding

5
"... önişlemci, eklenecek dosyayı derlemekle aynı dizinde arar." Bu ifade tamamen doğru değil. Bu soruya ilgi duydum çünkü asıl cevabın ne olduğunu merak ettim, ama bunun doğru olmadığını biliyorum, çünkü en azından gcc ile #include "dosyaadı ile belirtilen dosyaları arayacak ek bir içerme yolu belirttiğinizde. h "
Gabriel Güney

9
Cevabı beğenmeyenler, lütfen, yanlış olduğu yerde pratik bir örnek verin.
0kcats

1
Tabii ki, yakın zamanda bu sözdizimlerini 'aynı' kütüphaneden başlıklar eklerken karıştırdım ve yeniden tanımlama hatalarıyla sonuçlandım. Doğru anlarsam, #include <...>sistemde yüklü olan paketi ve #include "..."yakındaki depo sürümünü kullandım. Bunları geri alabilirim. Her iki şekilde de, paketlenmiş başlıktaki içerme muhafazasının önüne bir alt çizgi eklenir. (Sürüm niteleyicileri benim için daha anlamlı olsa da, paketler için bir kongre veya belki de ikisinin karıştırılmasını önlemenin bir yolu olabilir.)
John P

714

Bunu bilmenin tek yolu uygulamanızın belgelerini okumaktır.

Olarak Cı standart bölüm 6.10.2, 2-4 durumunu paragraf:

  • Formun bir ön işleme direktifi

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

    ve sınırlayıcılar arasında belirtilen sıra ile benzersiz olarak tanımlanan bir başlık için uygulama tanımlı bir sıra dizisini arar ve bu yönergenin başlığın tüm içeriğiyle değiştirilmesine neden olur . Yerlerin nasıl belirtildiği veya belirlenen başlık uygulama tarafından tanımlanır.<>

  • Formun bir ön işleme direktifi

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

    bu yönergenin , sınırlayıcılar arasında belirtilen sıra ile tanımlanan kaynak dosyanın tüm içeriğiyle değiştirilmesine neden olur ". Adı belirtilen kaynak dosya , uygulama tanımlı bir şekilde aranır. Bu arama desteklenmiyorsa veya arama başarısız olursa, yönerge okunmuş gibi yeniden işlenir

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

    >orijinal yönergeden aynı içerilen sıra ile ( varsa karakterler dahil ).

  • Formun bir ön işleme direktifi

    #include pp-tokens new-line

    (önceki iki formdan biriyle eşleşmeyen) izin verilir. includeYönerge sonrası önişlem belirteçleri , normal metinde olduğu gibi işlenir. (Şu anda bir makro adı olarak tanımlanan her tanımlayıcının yerini, önişleme belirteçlerinin yerine geçen liste alır.) Tüm değişikliklerden sonra ortaya çıkan yönerge, önceki iki formdan biriyle eşleşmelidir. A <ve bir >ön işleme belirteci çifti veya bir çift "karakter arasındaki bir ön işlem belirteci dizisinin tek bir başlık adı ön işlem belirtecinde birleştirildiği yöntem, uygulama tanımlıdır.

Tanımlar:

  • h-char: kaynak karakter kümesinin yeni satır karakteri hariç herhangi bir üyesi ve >

  • q-char: yeni satır karakteri dışında kaynak karakter kümesinin herhangi bir üyesi ve "



27
@piCookie hem <filename> hem de "filename", uygulama tanımlı yerleri arar. Peki fark nedir?
onmyway133

15
@Stefan, sadece INCLUDE_PATH hakkında hiçbir şey söylemeyen standardı aktarıyorum. Uygulamanız bunu yapabilir ve benimki yapamaz. Orijinal soru genel olarak C ve özellikle gcc (ki ben INCLUDE_PATH kullanır sanmıyorum) ya da Microsoft C (ki sanırım) ya da başka bir değil, bu yüzden genel olarak cevap verilemez ama bunun yerine her uygulamanın belgelerine başvurulmalıdır.
piCookie

12
Tüm bu durumlarda olduğu gibi, somut örnekler (özellikle ortak senaryoların) büyük ölçüde faydalı ve eşit derecede takdir edilmektedir. Gereksiz yere yaygın jenerik cevaplar o kadar pratik kullanıma sahip değildir.
vargonian

132
"C standardı nasıl ayrıntılı olabilir ve sorunuza cevap
vermeyebilir

287

<Ve> arasındaki karakter dizisi, benzersiz bir şekilde bir dosya olmayan bir başlığa karşılık gelir. Uygulamalar, karakter dizisini istedikleri gibi kullanmak için hemen hemen ücretsizdir. (Bununla birlikte, çoğunlukla dosya adı gibi davranın ve içerme yolunda , diğer yayınların durumu gibi bir arama yapın .)

Eğer #include "file"form verilmiş isimde bir dosya için, uygulama ilk görünüyor kullanılır destekleniyorsa. Desteklenmezse (veya desteklenmezse) veya arama başarısız olursa, uygulama diğer ( #include <file>) formu kullanılmış gibi davranır .

Ayrıca, üçüncü bir form vardır ve #includeyönerge yukarıdaki formların hiçbiriyle eşleşmediğinde kullanılır . Bu formda, #includedirektifin "işlenenleri" üzerinde bazı temel ön işlemler (makro genişletme gibi) yapılır ve sonucun diğer iki formdan biriyle eşleşmesi beklenir.


50
+1, bu muhtemelen en özlü ve doğru cevaptır. (PiCookie'nin cevabından alıntıladığı) standarda göre, tek gerçek fark "başlık" ve "kaynak dosya" dır. Arama mekanizması her iki şekilde de uygulama tanımlıdır. Çift tırnak işareti kullanmak, bir "kaynak dosya" eklemeyi planladığınız anlamına gelirken, köşeli ayraçlar, bir dosya içermeyebileceğiniz bir "üstbilgi" eklemek istediğiniz anlamına gelir.
Dan Moulding

3
Dan Moulding'in quest49'un cevabı hakkındaki yorumuna bakın; standart başlıkların dosya biçiminde olması gerekmez, yerleşik olabilirler.
aib

10
On yıldır "standart başlıklar dosya biçiminde olmak zorunda değil" okuyorum. Gerçek bir dünya örneği sunmak ister misiniz?
Maxim Egorushkin

12
@Maxim Yegorushkin: Mevcut herhangi bir gerçek dünya örneğini de düşünemiyorum; ancak, üstbilgilerin dosya olması gerekmiyorsa, MS-DOS için tam bir C11 derleyicisi bulunamaz. Bunun nedeni, bazı C11 üstbilgi adlarının "8.3" MS-DOS dosya adı sınırlamasıyla uyumlu olmamasıdır.
Dan Moulding

18
@MaximEgorushkin: VAX / VMS C derleyicisi, tüm C çalışma zamanı kitaplığı başlıklarını tek bir metin kitaplığı dosyasında (bir unix arşivine benzer) tuttu ve kitaplık dizinini oluşturmak için <ve arasındaki >anahtar olarak dizeyi kullandı .
Adrian McCarthy

117

Burada bazı iyi cevaplar C standardına atıfta bulunur, ancak POSIX standardını, özellikle c99 (örn. C derleyici) komutunun özel davranışını unutur .

Göre Açık Grubu Baz Özellikleri Issue 7 ,

-I dizini

Adları mutlak yol adı olmayan üstbilgileri aramak için kullanılan algoritmayı , normal yerlere bakmadan önce dizin yol adı ile adlandırılan dizine bakacak şekilde değiştirin . Bu nedenle, adları çift tırnak içine alınmış başlıklar ("") önce #include satırı ile dosyanın dizininde, daha sonra -I seçenekleri olarak adlandırılan dizinlerde ve son olarak olağan yerlerde aranır . İsimleri köşeli parantez içine alınmış ("<>") üstbilgiler için, üstbilgi yalnızca -I seçenekleri olarak adlandırılan dizinlerde ve daha sonra olağan yerlerde aranacaktır . -I seçeneklerinde belirtilen sırada aranacaktır.c99 komut çağrısında belirtilen dizinler .

Bu nedenle, POSIX uyumlu bir ortamda, POSIX uyumlu bir C derleyicisi ile, ilk önce #include "file.h"arama yapılacaktır , ifadeyle birlikte dosyanın bulunduğu dizin nerede , muhtemelen ilk olarak arayacak , sisteminiz nerede tanımlanır başlıklar için normal yerler (POSIX tarafından tanımlanmamış görünüyor)../file.h.#include#include <file.h>/usr/include/file.h/usr/include


1
Metnin kesin kaynağı nedir? IEEE Std 1003.1, 2013'ün normatif kısmından mı geliyor?
osgx

7
@osgx: c99C ifadesi için POSIX adı olan POSIX belirtiminde bu ifade (veya son derece benzer bir şey) bulunur . (POSIX 2008 standardı C11'e pek benzemiyordu; POSIX 2008'e 2013 güncellemesi atıfta bulunduğu C standardını değiştirmedi.)
Jonathan Leffler

1
Bu benim de ilk düşüncemdi. Gcc için manpage bunu diğerleri gibi içerir. Kütüphaneler için de benzer bir şey var -L.
Pryftan

50

GCC belgeleri , ikisi arasındaki fark hakkında şunları söylüyor :

Hem kullanıcı hem de sistem başlık dosyaları önişleme yönergesi kullanılarak eklenir ‘#include’. İki çeşidi vardır:

#include <file>

Bu varyant sistem başlık dosyaları için kullanılır. Standart sistem dizinleri listesinde dosya adlı bir dosyayı arar. Bu listeye dizinleri -Iseçeneğiyle başlatabilirsiniz (bkz. Çağırma ).

#include "file"

Bu varyant, kendi programınızın başlık dosyaları için kullanılır. Önce geçerli dosyayı içeren dizinde, daha sonra alıntı dizinlerinde ve daha sonra kullanılan dizinlerde dosya adlı bir dosya arar <file>. -iquoteSeçenek ile dizinleri tırnak dizinleri listesine ekleyebilirsiniz . Argümanı ‘#include’tırnak işareti veya açılı ayraçlar ile sınırlandırılmış olup, bu yorumlarda bir dize sabiti gibi davranacağını tanınmaz ve makro adları genişletilmiş değildir. Bu nedenle, #include <x/*y>adlı bir sistem başlık dosyasının eklenmesini belirtir x/*y.

Ancak, dosya içinde ters eğik çizgiler oluşursa, bunlar kaçış karakterleri olarak değil sıradan metin karakterleri olarak kabul edilir. C'deki dize sabitlerine uygun karakter çıkış dizilerinin hiçbiri işlenmez. Böylece, #include "x\n\\y"üç ters eğik çizgi içeren bir dosya adı belirtir. (Bazı sistemler '\' yol adı ayırıcısı olarak yorumlanır. Bunların tümü de ‘/’aynı şekilde yorumlanır . Yalnızca kullanımı en taşınabilir olanıdır ‘/’.)

Dosya adından sonraki satırda (yorumlar dışında) bir şey olması bir hatadır.


46

Şunları yapar:

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

ile .dosya rehberi ya da yer #includeiçerdiği ve / veya derleyici mevcut çalışma dizini ve / veyadefault_include_paths

ve

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

İçerideyse ./, <default_include_paths>bir fark yaratmaz.

Eğer mypath/myfilebaşka isimli dizini dahil, davranış tanımlanmamış.


12
Hayır, #include "mypath/myfile"eşdeğer değildir #include "./mypath/myfile". PiCookie'nin cevabının dediği gibi, çift tırnak işaretleri derleyiciye belirtilen yerlerde arama da dahil olmak üzere uygulama tanımlı bir şekilde arama yapmasını söyler #include <...>. (Aslında, muhtemelen eşdeğerdir ancak tek nedeni, örneğin, /usr/include/mypath/myfileolarak anılacaktır edilebilir /usr/include/./mypath/myfile-. En az on sistemleri Unix benzeri)
Keith Thompson

1
@Keith Thompson: Doğru, Linux kutumu düşünüyordum. Açıkçası farklı olabilir. Uygulamada olmasına rağmen, Posix olmayan işletim sistemi olarak Windows da yol ayırıcı olarak yorumlamaktadır / ./ da vardır.
Stefan Steiger

1
-L dizinyolu seçeneği daha sonra ekler dirpath için defaultincludepathsbaşka bir anlam veren karşıt olarak, .(yukarıda işaret edildiği gibi). Bu, hem o beklenen sonucu vardır #include "..."ve #include <...>arama dirpath
Protongun

1
Bence bu cevap yanlıştır, çünkü çift tırnak işaretleri içeren başlıkların her zaman geçerli çalışma dizininde arandığını ima eder. Arama mekanizması çok daha ayrıntılıdır; bu cevap eksik. Bu yorumu şikayet etmek ya da sızlanmak için eklemiyorum, çünkü sistem benden bu cevaba neden oy verdiğimi açıklamak için bir yorum eklememi istediğinden.
Carlo Wood

39

<file>Dahil arama yapmanın ön işlemcisi söyler -Idizinleri ve önceden tanımlanmış dizinlerde ilk .c dosyasının dizinde sonra. "file"Geçtiği kaynak dosyanın dizin aramak için önişlemci söyler ilk dönmek sonra ve-I ve önceden tanımlanmış. Tüm hedefler yine de aranır, sadece arama sırası farklıdır.

2011 standardı çoğunlukla "16.2 Kaynak dosya dahil etme" içindeki içerme dosyalarını tartışır.

2 Formun bir ön işleme direktifi

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

<ve> sınırlayıcıları arasında belirtilen sırada benzersiz olarak tanımlanan bir başlık için uygulama tanımlı bir sıra dizisini arar ve bu yönergenin başlığın tüm içeriğiyle değiştirilmesine neden olur. Yerlerin nasıl belirtildiği veya belirlenen başlık uygulama tarafından tanımlanır.

3 Formun bir ön işleme direktifi

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

bu yönergenin "sınırlayıcılar arasında belirtilen sıra ile tanımlanan kaynak dosyanın tüm içeriğiyle değiştirilmesine neden olur. Adlandırılmış kaynak dosya, uygulama tanımlı bir şekilde aranır. Bu arama desteklenmiyorsa veya arama başarısız olursa , yönerge okundu gibi yeniden işlenir

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

orijinal yönerge ile aynı özdeş dizilimle (varsa,> karakterler dahil).

Not "xxx"form düşüren <xxx>dosya bulunmazsa formu. Gerisi uygulama tanımlıdır.


4
Bu -Iişletmenin C standardında nerede belirtildiğine ilişkin bir referans verebilir misiniz ?
juanchopanza

1
Ben referans görmüyorum -I.
juanchopanza

2
Bu "uygulama tanımlı" kısımdır.

28

#include <file.h>derleyiciye "include" dizininde başlık aramasını söyler, örneğin MinGW için derleyicinin file.hC: \ MinGW \ include \ içinde veya derleyicinizin kurulu olduğu her yerde arayacağını belirtir.

#include "file"derleyiciye geçerli dizinde arama yapmasını söyler (yani kaynak dosyanın bulunduğu dizin) file.

-IGCC bayrağını, açılı parantez içeren bir içerme ile karşılaştığında, bundan sonraki dizindeki başlıkları da araması gerektiğini söylemek için kullanabilirsiniz -I. GCC, işaretten sonra dizine dizinmiş gibi davranacaktır includes.

Örneğin, şu adda bir dosyanız varsa: myheader.h kendi dizininizde#include <myheader.h> varsa, GCC'yi bayrakla çağırıp çağırmadığınızı söyleyebilirsiniz -I .(geçerli dizinde ekleri araması gerektiğini belirtir).

-IBayrak olmadan #include "myheader.h"dosyayı eklemek veya derleyicinizin dizinine taşımak myheader.hiçin kullanmanız gerekir include.


22

Standart olarak - evet, farklılar:

  • Formun bir ön işleme direktifi

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

    <ve >sınırlayıcılar arasında belirtilen sırada benzersiz olarak tanımlanan bir başlık için uygulama tanımlı bir sıra dizisini arar ve bu yönergenin başlığın tüm içeriğiyle değiştirilmesine neden olur. Yerlerin nasıl belirtildiği veya belirlenen başlık uygulama tarafından tanımlanır.

  • Formun bir ön işleme direktifi

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

    bu yönergenin, "sınırlayıcılar arasında belirtilen sıra ile tanımlanan kaynak dosyanın tüm içeriğiyle değiştirilmesine neden olur . Adı belirtilen kaynak dosya, uygulama tanımlı bir şekilde aranır. Bu arama desteklenmiyorsa veya arama başarısız olursa, yönerge okunmuş gibi yeniden işlenir

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

    >orijinal yönergeden aynı içerilen sıra ile ( varsa karakterler dahil ).

  • Formun bir ön işleme direktifi

    #include pp-tokens new-line

    (önceki iki formdan biriyle eşleşmeyen) izin verilir. includeYönerge sonrası önişlem belirteçleri , normal metinde olduğu gibi işlenir. (Şu anda bir makro adı olarak tanımlanan her tanımlayıcının yerini, önişleme belirteçlerinin yerine geçen liste alır.) Tüm değişikliklerden sonra ortaya çıkan yönerge, önceki iki formdan biriyle eşleşmelidir. A <ve bir >ön işleme belirteci çifti veya bir çift "karakter arasındaki bir ön işlem belirteci dizisinin tek bir başlık adı ön işlem belirtecinde birleştirildiği yöntem, uygulama tanımlıdır.

Tanımlar:

  • h-char: kaynak karakter kümesinin yeni satır karakteri hariç herhangi bir üyesi ve >

  • q-char: yeni satır karakteri dışında kaynak karakter kümesinin herhangi bir üyesi ve "

Standardın, uygulama tanımlı davranışlar arasında herhangi bir ilişki belirtmediğini unutmayın. İlk form, uygulama tanımlı bir şekilde, diğeri (muhtemelen diğer) uygulama tanımlı bir şekilde arar. Standart ayrıca belirli içerme dosyalarının mevcut olacağını belirtir (örneğin, <stdio.h>).

Resmi olarak derleyicinizin kılavuzunu okumalısınız, ancak normal olarak (geleneğe göre) #include "..."form #include, ilk önce bulunduğu dosyanın dizinini ve ardından #include <...>formun aradığı dizinleri (dahil etme yolu, örn. Sistem başlıkları) arar. ).


2
Bu çoğunlukla piCookie'nin yedi yıl önceki cevabı ile aynı metindir .
Kyle Strand

5
@KyleStrand Çünkü aynı metin standarttaki ilgili bölümün bir alıntısıdır - bu metin aynı olmalıdır . Asıl cevap aynı metin değildir ve biraz farklıdır - aynı zamanda uygulamanın belgelerinde yazıldığını da kabul ederken, bunların da geleneksel olarak yorumlanmasının (kullandığım derleyicilerin çoğunun veya tümünün saygı duyduğu) olduğunu da not ediyorum. .
skyking

2
IMO buradaki en iyi cevaptır, çünkü hem standardın söylediklerini hem de çoğu derleyicinin gerçekte ne yaptığını kapsar.
plugwash

17

Harika cevaplar için teşekkürler, esp. Adam Stelmaszczyk ve piCookie ve aib.

Birçok programcı gibi ben de "myApp.hpp"formu uygulamaya özgü dosyalar için kullanma gayri resmi kuralını ve <libHeader.hpp>kütüphane ve derleyici sistem dosyaları, yani belirtilen dosyalar /Ive INCLUDEortam değişkeni için formu standart olduğunu düşünerek yıllarca kullandım.

Bununla birlikte, C standardı arama sırasının uygulamaya özgü olduğunu ve taşınabilirliği karmaşık hale getirebileceğini belirtir. Daha da kötüsü, dahil etme dosyalarının nerede olduğunu otomatik olarak belirleyen reçel kullanıyoruz. Dahil etme dosyalarınız için göreli veya mutlak yollar kullanabilirsiniz. yani

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

MSVS'nin eski sürümleri çift ters eğik çizgi (\\) gerektiriyordu, ancak şimdi bu gerekli değil. Ne zaman değiştiğini bilmiyorum. 'Nix ile uyumluluk için eğik çizgi kullanın (Windows bunu kabul edecektir).

Eğer varsa gerçekten bu konuda endişeli, kullanım"./myHeader.h" , kaynak kodla aynı dizinde bulunan bir içerme dosyası için (şu anki, çok büyük projem, dağınık dosya adlarının çoğunu içeriyor - gerçekten bir yapılandırma yönetimi sorunu).

İşte MSDN açıklama kolaylık olması için burada kopyalanan).

Alıntılanan form

Önişlemci şu sırayla içerme dosyalarını arar:

  1. #İnclude deyimini içeren dosyayla aynı dizinde.
  2. Şu anda açılmış olan dizinlere, açıldıkları sıranın tersi sırada dosyalar dahildir
    . Arama, ana içerme dosyasının
    dizininde başlar ve herhangi bir büyükbaba veya büyükanne içerme dosyalarının dizinleri boyunca yukarı doğru devam eder.
  3. Her /Iderleyici seçeneği tarafından belirtilen yol boyunca .
  4. INCLUDEOrtam değişkeni tarafından belirtilen yollar boyunca .

Köşebent formu

Önişlemci şu sırayla içerme dosyalarını arar:

  1. Her /Iderleyici seçeneği tarafından belirtilen yol boyunca .
  2. Derleme, komut satırında, INCLUDEortam değişkeni tarafından belirtilen yollar boyunca gerçekleştiğinde .

16

En azından GCC sürüm <= 3.0 için, köşeli parantez formu dahil edilen dosya ile dahil edilen dosya arasında bir bağımlılık oluşturmaz.

Dolayısıyla, bağımlılık kuralları oluşturmak istiyorsanız (örnek için GCC-M seçeneğini kullanarak), bağımlılık ağacına dahil edilmesi gereken dosyalar için alıntılanan formu kullanmanız gerekir.

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


1
Evet - bağımlılık yaratmanın birkaç farklı yolu vardır. Bu onlardan biri ama tek değil.
Pryftan

15

İçin #include ""bir derleyici normalde içerdiğini içerir ve daha sonra diğer klasörler dosyanın klasörünü arar. İçin #include <>derleyici geçerli dosya klasörünü aramaz.


1
İnsanların neden katılmadıklarından emin değilim.
Maxim Egorushkin

Çoğu insanın sadece CWD'lerindeki dosyaları derlemesinden şüpheleniyorum. Foo dizinindeyseniz ve foo / unittest / bar.c dosyasını derliyorsanız ve bar.h'yi içeriyorsa, "bar.h" çalışır ve <bar.h> çalışmaz.

1
@Maxim insanlar katılmıyorum çünkü tarif ettiğiniz davranış standart C değildir
osvein

2
@Spookbuster Doğru, standart her ikisini de söylüyor <filename>ve "filename"uygulama tanımlı yerleri arayın.
Maxim Egorushkin

14

#İnclude <filename> komutunu kullandığınızda, C \ C ++ başlık dosyalarının (stdio.h \ cstdio, dize, vektör vb.) Dizinindeki dosyayı arayan önişlemci. Ancak, #include "dosyaadı" kullandığınızda: ilk olarak, ön dizinde geçerli dizinde dosyayı arıyor ve burada yoksa - C \ C ++ başlık dosyalarının dizininde arıyor.


1
Yıllarca mükemmel bir cevap verildikten sonra, neden bir tane gönderin, bu sadece açık bir şekilde yanlış? Her ne kadar yaygın olsa da, #includeyönerge kesinlikle dosyalarla ilgili değildir.
IInspectable

@Inspectable lütfen neden dosyalarla ilgili olmadığını açıklayın.
Behrooz Karjoo

11

Köşeli parantez içeren bir #include, eklenecek dosya için "uygulamaya bağlı yerlerin listesini" ("sistem başlıkları" demenin çok karmaşık bir yoludur) arar.

Tırnak işaretli bir #include yalnızca bir dosyayı arar (ve "uygulamaya bağlı bir şekilde", bleh). Bu, normal İngilizce'de, attığınız yolu / dosya adını uygulamaya çalışacak ve aksi takdirde bir sistem yolunu veya kurcalamayı önleymeyecektir.

Ayrıca, #include "" başarısız olursa, standart tarafından #include <> olarak yeniden okunur.

Gcc dokümantasyon gcc özgü değil standart olmalarına rağmen, ISO standartları avukat tarzı konuşmaktansa anlamak çok daha kolay bir (derleyici özel) açıklaması vardır.


Bununla birlikte, açılı ayraçlar veya tırnak işaretleri kullanmak, dosyaların dahil edilme şeklini etkilemez, tam olarak aynıdır: önişlemci, vermeden önce kodu içerme dosyalarından orijinal kaynak dosyaya kopyalayıp yapıştırarak büyük bir kaynak dosyası oluşturur. derleyiciye (önişlemci #define sustitution, #if
Evaluation

Çatışmalar ne olacak? Örneğin zlib.h, 'kullanıcı' arama yollarımda olduğumu ve sistem arama yolunda farklı bir sürümün mevcut olduğunu varsayalım, o zaman #include <zlib.h>sistem sürümünü #include "zlib.h"içeriyor ve kendiminkini içeriyor mu?
the_mandrill

Aha, kendi sorumu yanıtladı: stackoverflow.com/questions/21593/…
the_mandrill

Hem standart (lar) hem de tipik uygulama kurallarının, standart tarafından belirtilmediğinden, bunun bilinemez olduğunu belirtmek yerine, hem alakalı olduğunu kabul ettiğiniz için teşekkür ederiz .
Kyle Strand

10
#include "filename" // User defined header
#include <filename> // Standard library header.

Misal:

Buradaki dosya adı 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

Sınıf uygulamasında (örneğin, Seller.cppve dosyayı kullanacak diğer dosyalarda Seller.h), kullanıcı tarafından tanımlanan başlık şimdi aşağıdaki gibi dahil edilmelidir:

#include "Seller.h"

10
  • #include <> önceden tanımlanmış başlık dosyaları içindir

Üstbilgi dosyası önceden tanımlanmışsa, üstbilgi dosya adını köşeli parantez içine yazarsınız ve şöyle görünür (önceden tanımlanmış bir üstbilgi dosya adımız iostream varsayalım):

#include <iostream>
  • #include " " programlayıcının tanımladığı başlık dosyaları içindir

Siz (programcı) kendi başlık dosyanızı yazdıysanız, başlık dosyası adını tırnak işaretleri arasına yazarsınız. Diyelim ki adlı bir başlık dosyası yazdınız myfile.h, o zaman bu dosyayı eklemek için include direktifini nasıl kullanacağınıza bir örnektir:

#include "myfile.h"

2
Önceden tanımlanmış başlık dosyalarıyla hiç ilgisi yoktur. Aranacak konumlarla ilgilidir.
C Johnson

9

Buradaki cevapların çoğu, derleyicinin dosyayı bulmak için arayacağı yollara odaklanır. Çoğu derleyicinin yaptığı bu olsa da, uygun bir derleyicinin standart başlıkların etkileriyle önceden programlanmasına ve tedavi edilmesine izin verilir,#include <list> örneğin bir anahtar olarak ve bir dosya olarak var olmasına gerek yoktur.

Bu tamamen varsayımsal değildir. Bu şekilde çalışan en az bir derleyici var. Kullanımı #include <xxx>yalnızca standart başlıklarıyla önerilir.


9
#include <abc.h>

standart kütüphane dosyalarını dahil etmek için kullanılır. Böylece derleyici standart kütüphane başlıklarının bulunduğu yerleri kontrol edecektir.

#include "xyz.h"

derleyiciye kullanıcı tanımlı başlık dosyaları eklemesini söyler. Böylece derleyici geçerli klasördeki veya -Itanımlı klasördeki bu başlık dosyalarını kontrol edecektir .


7

C ++ 'da bir dosyayı iki şekilde ekleyin:

Birincisi #include, önişlemciye önceden tanımlanmış varsayılan konumda dosyayı aramasını söyler. Bu konum genellikle dosyaları dahil etme yolunu gösteren bir INCLUDE ortam değişkenidir.

İkinci tür ise #include "dosyaadı" dır.


7

Form 1 - # <xxx> ekleyin

İlk olarak, direktifin çağrıldığı geçerli dizinde başlık dosyasının varlığını arar. Bulunamazsa, önceden yapılandırılmış standart sistem dizinleri listesinde arama yapar.

Form 2 - # "xxx" ifadesini ekleyin

Bu, direktifin çağrıldığı geçerli dizinde başlık dosyasının varlığını arar.


Tam arama dizini listesi, hedef sisteme, GCC'nin nasıl yapılandırıldığına ve nereye kurulduğuna bağlıdır. GCC derleyicinizin arama dizini listesini -v seçeneğiyle çalıştırarak bulabilirsiniz.

- I dir komutunu kullanarak arama yoluna ek dizinler ekleyebilirsiniz .


Temel olarak, "xxx" formu geçerli dizinde arama yapmaktan başka bir şey değildir; eğer form geri düşüyorsa


3
İyi kurulmuş ve doğru cevapları olan daha eski bir soruyu cevaplamaya karar verirseniz, günün geç saatlerinde yeni bir yanıt eklemek size herhangi bir kredi getirmeyebilir. Bazı farklı yeni bilgileriniz varsa veya diğer cevapların yanlış olduğuna ikna olduysanız, elbette yeni bir cevap ekleyin, ancak aynı soruya genellikle sorulduktan uzun bir süre sonra aynı temel bilgileri veren 'yine başka bir cevap' kazandı ' Sana çok fazla kredi kazandırmaz.
Jonathan Leffler

1
@Jonathan Leffler Bana Darshan'ın yanıtı kadar özlü ve doğru olduğunu düşündüğünüz "köklü" cevaba işaret edebilir misiniz?
personal_cloud

1
#include "header.h"Formun açıklaması doğru değil @personal_cloud. PiCookie ve Yann Droneaud'un cevabının , bilgilerinin nereden geldiğini belirledikleri için en alakalı olduğunu düşünüyorum. En çok oy alan yanıtı da tatmin edici bulmuyorum.
Jonathan Leffler

Bu cevap neden üstte gösterilirken, iki cevap daha 650'den fazla oy veriyor? Bu cevap beni şaşırttı, çünkü gözlemlediğim davranışa uymuyor. Bunun nedeni, son cümlenin köşeli parantezlerden kaçmaması nedeniyle kırılmış olması olabilir. Ne demek istediğinden emin değilim.
Neonit

6

#include <filename>Bir sistem dosyası sevk edilirken kullanılır. Bu, /usr/includeveya gibi sistem varsayılan konumlarında bulunan bir başlık dosyasıdır /usr/local/include. Başka bir programa dahil edilmesi gereken kendi dosyalarınız için #include "filename"sözdizimini kullanmanız gerekir .


6

standart <kütüphane konumlarında "<dosyaadı>" aramaları

oysa "dosyaadı" geçerli dizinde de arama yapar.

İdeal olarak, standart C kütüphaneleri için <...> ve yazdığınız ve geçerli dizinde bulunan kütüphaneler için "..." kullanırsınız.


4
Hangi yeni bilgiler bu yanıtı diğerlerine ekler?
Daniel Langr

5

Basit genel kural, derleyici ile birlikte gelen başlık dosyalarını dahil etmek için açılı parantez kullanmaktır. Diğer başlık dosyalarını dahil etmek için çift tırnak kullanın. Çoğu derleyici bunu bu şekilde yapar.

1.9 - Başlık dosyaları , işlemci öncesi yönergeler hakkında daha ayrıntılı olarak açıklar. Eğer acemi bir programcıysanız, bu sayfa tüm bunları anlamanıza yardımcı olacaktır. Buradan öğrendim ve iş yerinde takip ediyorum.


4
#include <filename>

C / C ++ sisteminin veya derleyici kitaplıklarının başlık dosyasını kullanmak istediğinizde kullanılır. Bu kütüphaneler stdio.h, string.h, math.h vb. Olabilir.

#include "path-to-file/filename"

proje klasörünüzde veya başka bir yerde bulunan kendi özel başlık dosyanızı kullanmak istediğinizde kullanılır.

Önişlemciler ve başlık hakkında daha fazla bilgi için. C - Önişlemciler bölümünü okuyun .


3

#include <filename>

  • Önişlemci uygulamaya bağlı bir şekilde arama yapar. Derleyiciye, sistem başlık dosyalarının tutulduğu dizinde arama yapmasını söyler.
  • Bu yöntem genellikle standart başlık dosyalarını bulmak için kullanılır.

#include "filename"

  • Bu derleyiciye programın çalıştığı başlık dosyalarında arama yapmasını söyler. Başarısız olsaydı,#include <filename> sistem başlık dosyalarının depolandığı yerde bu başlık dosyasını arayın ve bu başlık dosyasını arayın.
  • Bu yöntem genellikle kullanıcı tanımlı başlık dosyalarını (kullanıcı tarafından oluşturulan başlık dosyaları) tanımlamak için kullanılır. Orada standart kütüphane çağırmak istiyorsanız bunu kullanmayın çünkü daha derleme zaman alır #include <filename>.

2

Geçerli yapılandırmaya dayalı olarak gcc kullanarak sisteminizde arama sırasını görmek için aşağıdaki komutu yürütebilirsiniz. Bu komut hakkında daha fazla bilgiyi burada bulabilirsiniz

cpp -v /dev/null -o /dev/null

Apple LLVM sürüm 10.0.0 (clang-1000.10.44.2)
Hedef: x86_64-apple-darwin18.0.0
parçacığı modeli: posix InstalledDir: Library / Developer / CommandLineTools / usr / bin
"/ Kütüphane / Geliştirici / CommandLineTools / usr / bin / clang" -cc1-triple x86_64-apple-macosx10.14.0 -Wdeprecated-objc-isa-usage -Werror = kullanımdan kaldırıldı-objc-isa-kullanım -E -disable-free - devre dışı bırak-llvm-verifier -discard-değer-isimleri -main-dosya-adı null -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -fno-katı-dönüş -masm-ayrıntılı - munwind-tables -target-cpu penryn -dwarf-sütun-info -debugger-tuning = lldb -target-linker-sürüm 409.12 -v -kaynak-dir /Library/Developer/CommandLineTools/usr/lib/clang/10.0.0 - isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk -I / usr / local / include -fdebug-derleme-dir / Kullanıcılar / hogstrom -ferror-limit 19 -fmessage-length 80 -stack-protector 1 -fblocks -fencode-genişletilmiş-blok-imza -fobjc-runtime = macosx-10.14.0 -fmax-type-align = 16 -fdiagnostics-show-option -fcolor-diagnostics -traditional-cpp -o - -xc / dev / null
clang -cc1 sürüm 10.0.0 (clang-1000.10.44.2) varsayılan hedef x86_64-apple-darwin18.0.0 mevcut olmayan dizini yoksayıyor "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/local/include" yoksayılıyor "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/Library/Frameworks"
#include "..." dizini burada başlar:
#include <...> arama burada başlar:
/ usr / local / include
/ Kütüphane / Geliştirici / 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 / Sistem / Kütüphane / Çerçeveler (çerçeve dizini)
Arama listesinin sonu.


1
#include <file> 

Varsayılan include dizininin bulunduğu bir dosya içerir.

#include "file" 

Geçerli dizine derlendiği dosyayı içerir.


-2

#İnclude deyimini yazmanın iki yolu vardır.

#include"filename"
#include<filename>

Her formun anlamı

#include"mylib.h"

Bu komut, mylib.hayarlanmış olan içerme arama yolunda belirtildiği gibi geçerli dizindeki dosyayı ve belirtilen dizin listesini arar.

#include<mylib.h>

Bu komut mylib.hyalnızca belirtilen dizin listesindeki dosyayı arar .

İçerme arama yolu, dahil edilen dosya için aranacak dizin listesinden başka bir şey değildir.Farklı C derleyicileri, arama yolunu farklı şekillerde ayarlamanıza izin verir.


1
İyi kurulmuş ve doğru cevapları olan daha eski bir soruyu cevaplamaya karar verirseniz, günün geç saatlerinde yeni bir yanıt eklemek size herhangi bir kredi getirmeyebilir. Bazı farklı yeni bilgileriniz varsa veya diğer cevapların yanlış olduğuna ikna olduysanız, elbette yeni bir cevap ekleyin, ancak aynı soruya genellikle sorulduktan uzun bir süre sonra aynı temel bilgileri veren 'yine başka bir cevap' kazandı ' Sana çok fazla kredi kazandırmaz.
Jonathan Leffler
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.