#İfndef ve #define neden C ++ başlık dosyalarında kullanılıyor?


496

Genellikle başlık dosyalarının başlangıcında böyle bir kod görüyorum:

#ifndef HEADERFILE_H
#define HEADERFILE_H

Ve dosyanın sonunda

#endif

Bunun amacı ne?


36
+1 - Ben de aynı şüphem vardı ve burada çok daha iyi bir cevap aldım, gelecek ziyaretçiler için yararlı olabilir: stackoverflow.com/q/3246803/1134940
Abid Rahman K

6
Buna #pragma'yı bir kez de kullanabileceğinizi eklemek istiyorum , tek yapmanız gereken bu ve ifndef ile aynı amaca hizmet ediyor. İkisinin karşılaştırması için bkz. Stackoverflow.com/questions/1143936/…
Boyut

3
A'nın ne olduğunu belirtmek en iyisi #pragma: derleyiciye özgü bir özelliği etkinleştirir. Her ne kadar #pragma onceolduğu çok yaygın olarak desteklenen, bu standart dışı bu.
Potatoswatter

3
@Boyut: GNU'nun kendi belgeleri ( info cppveya buraya bakın ) "tüm ön işlemciler tarafından tanınmıyor, bu nedenle taşınabilir bir programda ona güvenemezsiniz" diyor. Ve GNU cpp, ortak ve taşınabilir #ifndefdeyimi optimize eder, böylece aynı derecede verimlidir #pragma once.
Keith Thompson

3
Dikkate alınması gereken bazı noktalar: Alt çizgiyle başlayan bir makro adı kullanmayın; bu tanımlayıcılar uygulamaya ayrılmıştır. Daha kurnazca, #ifndef HEADERFILE_Hbaşlığın adı ile başlayan uygulamanın ad alanını ihlal edebilir E; ile başlayan tanımlayıcılar Eve bir rakam veya büyük harf ayrılır <errno.h>. Ben öneririm #ifndef H_HEADERFILE.
Keith Thompson

Yanıtlar:


526

Bunlara #include korumaları denir .

Başlık eklendikten sonra, benzersiz bir değerin (bu durumda HEADERFILE_H) tanımlanıp tanımlanmadığını kontrol eder. Sonra tanımlanmamışsa, onu tanımlar ve sayfanın geri kalanına kadar devam eder.

Kod tekrar dahil edildiğinde, ilk ifndefbaşarısız olur ve boş bir dosyaya neden olur.

Bu, tipler, sıralamalar ve statik değişkenler gibi tanımlayıcıların çift bildirimini önler.


1
Koning Baard XIV: VC bile #pragma onceaynı şeyi yapıyor :-)
Joey

95
Ayrıca yinelemeli kapanmaları önler ... "alice.h" ifadesinin "bob.h" ve "bob.h" ifadesi "alice.h" öğelerini ve bunların korumaları içermediğini düşünün ...
Kevin Dungs

@Kevin: Demek istediğim bu. Ben manipüle etmek için form tarafından açılan bir formu manipüle etmek istedim. Çok fazla hata gaveme ve ne yapacağımı bilmiyordum.

6
@ :Οеу: #pragma oncetaşınabilir değil; ortak #ifndefdeyim önerilir.
Keith Thompson

2
@CIsForCookies "Bir tanım kuralı" nı favori arama motorunuza ekleyin.
David Schwartz

33
#ifndef <token>
/* code */
#else
/* code to include if the token is defined */
#endif

#ifndefverilen belirtecin #defineddosyada mı yoksa içerilen dosyada mı olduğunu kontrol eder ; değilse, kod ile kapanma #elseveya yoksa #else, #endifdeyimi arasındaki kodu içerir . #ifndefgenellikle dosya eklendikten sonra bir jeton tanımlayarak ve jetonun dosyanın üst kısmında ayarlanmadığını kontrol ederek başlık dosyalarını idempotent yapmak için kullanılır.

#ifndef _INCL_GUARD
#define _INCL_GUARD
#endif

4
Alt çizgiyle başlayan tanımlayıcılar saklıdır; onları kendiniz tanımlamamalısınız. Gibi bir şey kullanın #ifndef H_HEADER_NAME.
Keith Thompson

5
Bu eski bir yorum olduğunu biliyorum, ama aslında alt çizgi kısıtlama sadece "dış tanımlayıcılar" - derlenmiş nesnenin sembol tablosunda, yani genel değişkenler ve işlev adları sonuçlanabilir tanımlayıcılar için geçerlidir. Makro adları için geçerli değildir.
Stu

1
Stu'nun yorumu doğru mu? Sadece stackoverflow.com/questions/228783/… okudum ve şimdi o kadar emin değilim.
Will

9

Bu, aynı başlık dosyasının birden çok kez eklenmesini önler.

#ifndef __COMMON_H__
#define __COMMON_H__
//header file content
#endif

Bu başlık dosyasını birden çok dosyaya eklediğinizi varsayalım. Bu nedenle, ilk kez __COMMON_H__ tanımlanmadığında tanımlanır ve başlık dosyası dahil edilir.

Bir dahaki sefere __COMMON_H__ tanımlanır, bu yüzden tekrar içermez.


1

Bunlara ifdef veya nöbetçi koruma denir.

Küçük bir program yazıyorsanız, gerekli olmadığı düşünülebilir, ancak proje büyüdükçe, kasıtlı olarak veya kasıtsız olarak bir dosya birçok kez dahil edebilirsiniz, bu da zaten bildirilen değişken gibi derleme uyarısına neden olabilir.

#ifndef checks whether HEADERFILE_H is not declared.
#define will declare HEADERFILE_H once #ifndef generates true.
#endif is to know the scope of #ifndef i.e end of #ifndef

#İfndef doğru ürettiği anlamına gelmezse, yalnızca #ifndef ve #endif arasındaki bölüm aksi halde çalıştırılmaz. Bu, tekrar tanımlayıcıların, numaralandırmaların, yapıların vb.

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.