Soru #İnclude ve #include "filename" arasındaki fark nedir?


C ve C ++ programlama dillerinde, açılı ayraçlar kullanma ve tırnak içindeki tırnakları kullanma arasındaki fark nedir? include Açıklama, aşağıdaki gibi?

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

1813
2017-08-22 01:40


Menşei


gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC6 - legends2k
GCC kendi başlık dosyalarını bulmak için nerede görünüyor - theoretisch


Cevaplar:


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

İçin #include <filename> önişlemci, normalde, derleyici / IDE tarafından önceden belirlenmiş arama dizinlerinde, uygulamaya bağımlı bir şekilde arar. Bu yöntem normal olarak standart kitaplık başlık dosyalarını dahil etmek için kullanılır.

İçin #include "filename" önişlemci önce yönerge içeren dosya ile aynı dizinde arar ve daha sonra #include <filename> form. Bu yöntem normalde programlayıcı tanımlı üstbilgi dosyalarını içermek için kullanılır.

GCC'de daha eksiksiz bir açıklama mevcuttur. arama yolları ile ilgili belgeler.


1046
2017-08-22 01:40



Deyim: "önişlemci aynı dizinde arar ..." uygulamada doğru olabilir, ancak standart, adlandırılmış kaynak dosyasının "uygulama tanımlı bir şekilde aranır" olduğunu belirtir. PiCookie'den cevaplara bakın. - Richard Corden
Cevabınız "doğru" gibi görünebilir, ancak bu, uygulamaların ne kadarının sözleşmeye göre çalıştığından, aib ve piCookie'nin cevaplarına yakından bakmalısınız. İkisi de (C standardının ifadesiyle desteklenen) gerçek ayrımın bir “kaynak dosya” nın (“kaynak”) dahil edilmesine karşı bir “başlık” içerdiğini (ve hayır, bu “.h” vs. ”anlamına gelmediğine işaret ediyor). c "). Bu bağlamda "Kaynak dosya" (genellikle ve hemen hemen her zaman olmalıdır) bir ".h" dosyası olabilir. Bir başlığın mutlaka bir dosya olması gerekmez (bir derleyici, örneğin bir dosyada değil, statik olarak kodlanmış bir başlık içerebilir). - Dan Moulding
"... önişlemci, dosyanın dahil edilmesi için dosya olarak derlenen dosya ile aynı dizinde arar." Bu ifade tamamen doğru değil. Bu soruyla ilgileniyordum çünkü asıl cevabın ne olduğunu merak ettim, ama bunun doğru olmadığını biliyorum çünkü en azından gcc ile ek bir yol belirtip -c ile belirtilmiş olan dosyaları aramalıyım. h" - Gabriel Southern
Cevabı beğenmeyenler, lütfen, yanlış olduğu yerde pratik bir örnek verin. - 0kcats
Tabii ki, bu sözdizimini son zamanlarda 'aynı' kitaplıktan başlıkları dahil ettiğinde karıştırdım ve yeniden tanımlama hataları ile bitti. Eğer doğru anlıyorsam, #include <...> sistemde yüklü paketi kullandı ve #include "..." Yakındaki depo sürümünü kullandı. Bunları geriye alabilirim. Her iki durumda da paketlenmiş başlıktaki koruma görevlisi bir alt çizgi ile öneklenir. (Bu, sürüm eleme sahiplerinin bana daha mantıklı gelmesine rağmen, paketlerin bir kuralı ya da ikisini karıştırmayı kasten önlemenin bir yolu olabilir.) - John P


Bilmenin tek yolu, uygulamanızın belgelerini okumaktır.

İçinde C standardıbölüm 6.10.2, paragraf 2 ila 4 durumu:

  • Formun ön işlem yönergesi

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

    belirtilen belirtilen sıraya göre benzersiz bir şekilde tanımlanan bir başlık için uygulama tanımlı yerler dizisini arar. < ve > sınırlayıcılar ve bu yönergenin başlığın tüm içeriği tarafından değiştirilmesine neden olur. Yerlerin nasıl belirtildiği veya tanımlanan üstbilginin uygulama tanımlaması nasıl yapılır?

  • Formun ön işlem yönergesi

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

    Bu yönergenin, belirtilen sırayla belirtilen kaynak dosyanın tüm içeriği tarafından değiştirilmesine neden olur. " sınırlayıcı. Adlandırılmış 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
    

    aynı içeren dizi ile (dahil olmak üzere > varsa, orijinal karakterler   direktif.

  • Formun ön işlem yönergesi

    #include pp-tokens new-line
    

    (önceki iki formdan biriyle uyuşmayan) izin verilir. Sonra önişlemci jetonları include Direktifte, normal metinde olduğu gibi işlenir. (Şu anda bir makro adı olarak tanımlanmış her tanımlayıcı, ön işlem belirteçlerinin yedek listesi ile değiştirilir.) Tüm değiştirmelerden sonra ortaya çıkan yönerge, önceki iki formdan biriyle eşleşmelidir. Bir önişleme belirteçleri dizisi arasında bir yöntem < ve bir > ön işlem belirteç çifti veya bir çift " Karakterler tek bir başlık isminde birleştirilir ön işleme belirteci, uygulama tanımlıdır.

Tanımlar:

  • h-char: Yeni satır karakteri dışında kaynak karakter kümesinin herhangi bir üyesi ve >

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


594
2017-09-16 21:06



İlgili: uygulama g ++ ve görsel c ++ - Alexander Malakhov
@piCookie hem <filename> hem de "filename", uygulama tanımlı yerler için arama yapar. Peki fark nedir? - onmyway133
@Stefan, sadece INCLUDE_PATH hakkında bir şey söylemeyen standardın alıntı yapıyorum. Uygulamanız bunu yapabilir ve benim olmayabilir. Orijinal soru genel olarak C ve spesifik olarak gcc (INCLUDE_PATH kullandığını sanmıyorum) veya Microsoft C (bence bunu yapar) veya başka bir şey değildir, bu yüzden genel olarak cevaplanamaz, ancak her bir uygulamanın belgelerine başvurulmalıdır. - piCookie
Tüm bu durumlarda olduğu gibi, somut örnekler (özellikle ortak senaryolar) büyük ölçüde faydalıdır ve eşit olarak takdir edilmektedir. Aşırı geniş generik cevaplar pratikte çok fazla kullanılmaz. - vargonian
"İşte C standardı nasıl detay verilebilir ve sorunuza cevap veremez" - anatolyg


<Ve> arasındaki karakter dizisi, mutlaka bir dosya olmayan, bir üstbilgiye benzersiz olarak işaret eder. Uygulamalar, karakter dizisini istedikleri gibi kullanmak için oldukça özgürdür. (Çoğunlukla, sadece bir dosya adı olarak davranın ve arama yapın. yol eklediğer mesajların durumu gibi.)

Eğer #include "file" form kullanılır, uygulama ilk olarak desteklenen isminde bir dosyaya bakar. Değilse (desteklenen) veya arama başarısız olursa, uygulama diğer gibi davranır (#include <file>) formu kullanıldı.

Ayrıca, üçüncü bir form var ve ne zaman kullanılır #include yönerge, yukarıdaki formlardan hiçbiriyle uyuşmuyor. Bu formda, bazı temel ön işleme (makro genişletme gibi) "işlenenleri" üzerinde yapılır. #include Direktif ve sonuç iki diğer formdan biriyle eşleşmesi bekleniyor.


215
2017-09-08 17:43



+1, bu muhtemelen burada en özlü ve doğru cevaptır. Standartlara göre (hangi cevabından piCookie alıntılar), sadece gerçek fark "kaynak dosya" ya karşı "başlık" dır. Arama mekanizması her iki şekilde de uygulama tanımlıdır. Çift tırnak kullanmak, bir "kaynak dosya" eklemeyi amaçladığınız anlamına gelirken, köşeli parantezler demek istediğimiz gibi, bir dosya içermeyeceğiniz anlamına gelen bir "başlık" eklediğiniz anlamına gelir. - Dan Moulding
Dan Moulding'in yorumu49'un cevabıyla ilgili görüşüne bakın; Standart başlıkların dosya biçiminde olması gerekmez, yerleşik olabilirler. - aib
Ben on yıl boyunca bu "standart başlıkların dosya biçiminde olması gerekmiyor" okuyorum. Gerçek bir dünya örneği sağlamaya özen gösterilsin mi? - Maxim Egorushkin
@Maxim Yegorushkin: Herhangi bir gerçek dünya örneğini düşünemiyorum; ancak, üstbilgiler dosya olmak zorunda olmadıkça, MS-DOS için tam bir C11 derleyicisi bulunamaz. Bunun nedeni bazı C11 başlık adlarının "8.3" MS-DOS dosya adı sınırlamasıyla uyumlu olmamasıdır. - Dan Moulding
@MaximEgorushkin: VAX / VMS C derleyicisi, tüm C çalışma zamanı kitaplığı başlıklarını tek bir metin kitaplığı dosyasında (unix arşivine benzer şekilde) sakladı ve dizeyi < ve > kütüphaneye endeksleme anahtarı olarak. - Adrian McCarthy


Bazı iyi cevaplar C standardına referanslar verir, ancak POSIX standardını, özellikle de c99 (ör. C derleyici) Komut.

Göre Açık Grup Temel Özellikleri Sayı 7,

-BEN  rehber

Adlarıyla adlandırılmış dizine bakmak için adlarını mutlak yol adları olmayan üstbilgileri aramak için algoritmayı değiştirin. rehber olağan yerlere bakmadan önce yol adı. Böylelikle, isimleri çift tırnak ("") içerisinde bulunan başlıklar, ilk önce dosyanın dizininde aranır. #Dahil etmek satır, sonra dizinlerde -BEN seçenekler ve her zamanki yerlerde son. Adları köşeli parantezler ("<>") içine alınan başlıklar için, başlık sadece içinde isimlendirilen dizinlerde aranacaktır. -BEN seçenekler ve daha sonra normal yerlerde. Dizinler -BEN seçenekler belirtilen sırayla aranmalıdır. Uygulamalar, bu seçeneğin en az on örneğini tek bir c99 komut çağırma.

POSIX uyumlu bir C derleyicisiyle, POSIX uyumlu bir ortamda, #include "file.h" büyük olasılıkla aramak için gidiyor ./file.h ilk, nerede . ile dosya nerede dizin #include açıklama yaparken #include <file.h>, büyük olasılıkla aramak için gidiyor /usr/include/file.h ilk, nerede /usr/include sisteminiz tanımlandı mı olağan yerler başlıklar için (POSIX tarafından tanımlanmamıştır).


92
2017-07-20 09:29



Metnin tam kaynağı nedir? IEEE Std 1003.1, 2013 normatif bölümünden mi? - osgx
@osgx: Bu ifade (veya son derece benzer bir şey) POSIX belirtiminde bulunur. c99 - C derleyicisinin POSIX ismi. (POSIX 2008 standardı C11'e pek atıfta bulunamazdı; 2013 güncellemesinin POSIX 2008'e atıfta bulunduğu C standardı değişmedi.) - Jonathan Leffler


Yapar:

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

ile . dosyanın bulunduğu dizinin #include derleyicinin ve / veya derleyicinin geçerli çalışma dizininde bulunur ve / veya default_include_paths

ve

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

Eğer ./ içinde <default_include_paths>o zaman fark etmez.

Eğer mypath/myfile başka bir dizin içerir, davranış tanımsızdır.


36
2018-02-08 11:45



Yok hayır, #include "mypath/myfile" eşdeğer değildir #include "./mypath/myfile". PiCookie'nin cevabı dediği gibi, çift tırnaklar derleyiciye uygulama tanımlı bir şekilde arama yapmasını söyler. #include <...>. (Aslında, muhtemelen eşdeğerdir, ancak sadece /usr/include/mypath/myfile olarak anılabilir /usr/include/./mypath/myfile - en azından Unix benzeri sistemlerde.) - Keith Thompson
@Keith Thompson: Doğru, Linux kutumu düşünüyordum. Açıkçası farklı olabilirdi. Her ne kadar pratikte olsa da, Windows, Posix olmayan işletim sistemi olarak da, yol ayırıcı olarak yorumluyor ve / veya var. - Stefan Steiger
-L dizinyolu seçenek daha sonra ekler dizinyolu göre defaultincludepaths, başka bir anlam vermek yerine . (yukarıda belirtildiği gibi). Bunun beklenen sonucu hem #include "..." ve #include <...> araştır dizinyolu - Protongun
Bu cevabın yanlış olduğunu düşünüyorum, çünkü çift tırnak içine alınan başlıkların her zaman geçerli çalışma dizininde arandığını ima eder. Arama mekanizması daha detaylıdır; bu cevap eksik. Bu yorumu şikayete veya şerefine eklemiyorum, ama sistem bu cevabı neden reddettiğimi açıklamak için bir yorum eklememi istediği için. - Carlo Wood


GCC belgeleri diyor ikisi arasındaki fark hakkında aşağıdakiler:

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

#include <file>

Bu varyant sistem başlık dosyaları için kullanılır. Sistem dizinlerinin standart listesinde dosya adında bir dosya arar. Bu listeye dizinleri ekleyebilirsiniz. -I seçenek (bkz. yakarma).

#include "file"

Bu varyant kendi programınızın başlık dosyaları için kullanılır. Geçerli dosyayı içeren dizinde önce dosya adında bir dosyayı arar, ardından da alıntı dizinlerinde ve sonra aynı dizinler kullanılır. <file>. Dizinleri teklif dizinlerine listeye ekleyebilirsiniz. -iquote seçeneği.     Argüman ‘#include’Tırnak işaretleri veya köşeli parantezler ile sınırlandırılmış olsun, yorumların tanınmadığı bir dizge sabiti gibi davranır ve makro adları genişletilmez. Böylece, #include <x/*y> adında bir sistem üstbilgisi dosyasının eklenmesini belirtir x/*y.

Ancak, dosya içinde ters eğik çizgi oluşursa, karakterlerden kaçmak yerine sıradan metin karakterleri olarak kabul edilirler. C'deki dizi 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 path \ 'bir pathname ayırıcısı olarak yorumluyor. ‘/’ aynı yol. Sadece kullanımı en taşınabilir ‘/’.)

Dosya adından sonra satırda herhangi bir şey (yorumlar dışında) varsa bu bir hatadır.


30
2018-01-14 04:52





<file> önişlemcinin arama yapmasını söyler -I dizinler ve önceden tanımlanmış dizinler ilkdaha sonra .c dosyasının dizininde. "file" include, önişlemcinin kaynak dosya dizinini aramasını söyler ilkve sonra -I ve önceden tanımlanmış. Tüm hedefler zaten arandı, sadece arama sırası farklı.

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

2 Formun ön işlem yönergesi

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

benzersiz bir şekilde tanımlanmış bir başlık için uygulama tanımlı yerler dizisini arar   <ve> sınırlayıcılar arasında belirtilen diziyi oluşturur ve   bu direktifin başlığın tüm içeriği ile değiştirilmesi.   Yerler nasıl belirtilir veya başlık tanımlanır   Uygulama tanımlı.

3 Formun ön işlem yönergesi

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

bu yönerge tarafından tanımlanan kaynak dosyanın tüm içeriği tarafından değiştirilmesine neden olur.   "sınırlayıcılar arasında belirtilen dizidir. Adlandırılmış kaynak dosya   Uygulama tanımlı bir şekilde araştırıldı. Bu arama   desteklenmiyorsa veya arama başarısız olursa, yönerge şu şekilde yeniden işlenir:   eğer okursa

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

orijinal yönergelerin aynısını içeren diziyle (varsa> karakterler dahil).

Bunu not et "xxx" form bozunur <xxx> dosya bulunamazsa formu. Gerisi uygulama tanımlı.


23
2017-09-03 12:17



C standardında bu noktaya bir referans verebilir misiniz? -I iş belirtildi mi? - juanchopanza
@juanchopanza yapıldı. Ayrıca en iyi cevaba bakınız :) - Arkadiy
Referans görmüyorum -I. - juanchopanza
Bu "uygulama tanımlı" bölümü. - Arkadiy
İç çekmek. Ben senin cevabın, sesin dilde belirtilmiş bir şeymiş gibi ses çıkarmasını sağlıyorsun. - juanchopanza


Standart olarak - evet, farklılar:

  • Formun ön işlem yönergesi

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

    belirtilen belirtilen sıraya göre benzersiz bir şekilde tanımlanan bir başlık için uygulama tanımlı yerler dizisini arar. < ve > sınırlayıcılar ve bu yönergenin başlığın tüm içeriği tarafından değiştirilmesine neden olur. Yerlerin nasıl belirtildiği veya tanımlanan üstbilginin uygulama tanımlaması nasıl yapılır?

  • Formun ön işlem yönergesi

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

    Bu yönergenin, belirtilen sırayla belirtilen kaynak dosyanın tüm içeriği tarafından değiştirilmesine neden olur. " sınırlayıcı. Adlandırılmış 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
    

    aynı içeren dizi ile (dahil olmak üzere > varsa, orijinal karakterler   direktif.

  • Formun ön işlem yönergesi

    #include pp-tokens new-line
    

    (önceki iki formdan biriyle uyuşmayan) izin verilir. Sonra önişlemci jetonları include Direktifte, normal metinde olduğu gibi işlenir. (Şu anda bir makro adı olarak tanımlanmış her tanımlayıcı, ön işlem belirteçlerinin yedek listesi ile değiştirilir.) Tüm değiştirmelerden sonra ortaya çıkan yönerge, önceki iki formdan biriyle eşleşmelidir. Bir önişleme belirteçleri dizisi arasında bir yöntem < ve bir > ön işlem belirteç çifti veya bir çift " Karakterler tek bir başlık isminde birleştirilir ön işleme belirteci, uygulama tanımlıdır.

Tanımlar:

  • h-char: Yeni satır karakteri dışında kaynak karakter kümesinin herhangi bir üyesi ve >

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

Standardın, uygulama tarafından tanımlanan davranışlar arasında herhangi bir ilişki olmadığını söylemediğini unutmayın. İlk form, bir uygulama tanımlı şekilde ve diğeri (muhtemelen diğer) uygulama tanımlı bir şekilde arar. Standart ayrıca belirli bazı dosyaların bulunacağını belirtir (örneğin, <stdio.h>).

Resmi olarak derleyicinizin kılavuzunu normalde (gelenekle) okumak zorundasınız. #include "..." form, dosyanın bulunduğu dizini arar. #include önce, sonra dizinleri bulundu #include <...> form aramaları (içerme yolu, örneğin sistem üstbilgileri).


16
2017-08-18 06:21



Bu çoğunlukla piCookie'nin cevabı ile aynıdır. Yedi yıl daha erken. - Kyle Strand
@KyleStrand Çünkü aynı metin standarttaki ilgili bölümün bir alıntıdır - metin meli aynı olmak Asıl cevap aynı metin değildir ve biraz farklıdır - aynı zamanda uygulamanın dokümantasyonunda yazılacağını da fark ettim, ayrıca bunların geleneksel bir şekilde yorumlandığına da dikkat etmeliyim (çoğu derleyicinin saygılarımı kullandım) . - skyking
IMO, buradaki en iyi cevaptır çünkü hem standardın ne söylediğini hem de çoğu derleyicinin gerçekte ne yaptığını kapsar. - plugwash


Büyük cevaplar için teşekkürler, özellikle. Adam Stelmaszczyk ve piCookie ve aib.

Birçok programcı gibi, "myApp.hpp" uygulamaya özel dosyalar için form ve <libHeader.hpp> kütüphane ve derleyici sistem dosyaları için form, yani /I ve INCLUDE çevre değişkeni, yıllardır standart olduğunu düşünüyordu.

Bununla birlikte, C standardı, arama sırasının uygulamaya özgü olduğunu ve taşınabilirliği karmaşıklaştırabileceğini belirtmektedir. Daha da kötüsü yapmak için, içerme dosyalarının nerede olduğunu otomatik olarak belirleyen sıkışmayı kullanırız. Ekleme dosyalarınızın göreli veya mutlak yollarını kullanabilirsiniz. diğer bir deyişle

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

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

Eğer sen Gerçekten mi bunun için endişelen, kullan "./myHeader.h" kaynak koduyla aynı dizinde bulunan bir dosya için (şu anki, çok büyük projemde bazı çoğaltılmış dosya adlarının yanı sıra bir yapılandırma yönetimi sorunu vardır).

Burada MSDN açıklaması rahatınız için buraya kopyalandı).

Belirtilen form

Önişlemci, dosyaları şu sırayla içerir:

  1. #İnclude ifadesini içeren dosyayla aynı dizinde.
  2. Şu anda açılan dosyaların dizinlerinde, ters sırada
        açıldılar. Arama, ana dosyanın dizininde başlar ve
        herhangi bir büyükbabaların dizinleri ile yukarı doğru devam eder dosyaları içerir.
  3. Her biri tarafından belirtilen yol boyunca /I derleyici seçeneği.
  4. Tarafından belirtilen yollar boyunca INCLUDE Çevre değişkeni.

Köşebent formu

Önişlemci, dosyaları şu sırayla içerir:

  1. Her biri tarafından belirtilen yol boyunca /I derleyici seçeneği.
  2. Komut satırında derleme yapılırken, tarafından belirtilen yollar boyunca INCLUDE Çevre değişkeni.

12
2017-10-14 23:51