2009-10-31 248 views
321

我已經看到這樣的代碼通常在頭文件開始:爲什麼在C++頭文件中使用#ifndef和#define?

#ifndef HEADERFILE_H 
#define HEADERFILE_H 

,並在文件的結尾是

#endif 

這樣做有什麼目的?

+22

+1 - 我也有同樣的疑問,並在這裏得到更多的好答案,可能對未來的訪問者有用:http://stackoverflow.com/q/3246803/1134940 – 2012-12-11 05:27:31

+5

我想補充說,你可以也可以使用** #pragma once **,這就是你所要做的,它和ifndef具有相同的用途。有關這兩者的比較,請參閱:http://stackoverflow.com/questions/1143936/pragma-once-vs-include-guards – Dimension 2013-06-01 16:12:33

+2

最好提一下'#pragma':它激活編譯器特定的功能。儘管'#pragma once'被廣泛支持,但它並不標準。 – Potatoswatter 2013-06-01 16:41:10

回答

369

這些被稱爲#include guards

包含標題後,它會檢查是否定義了唯一值(在此例中爲HEADERFILE_H)。然後,如果沒有定義,它定義它並繼續到頁面的其餘部分。

當代碼再次被包含時,第一個ifndef失敗,導致一個空白文件。

可以防止任何標識符(如類型,枚舉和靜態變量)的雙重聲明。

+3

嗯interresting。我曾經退出VC++因爲它給了我關於雙重定義的錯誤。沒關係,我現在是一個Objective-C編碼器=) – 2009-10-31 10:19:15

+0

Koning Baard XIV:VC甚至有一個'#pragma once'這樣做:-) – Joey 2009-10-31 10:23:03

+63

另外它可以防止遞歸包含...想象一下,「alice.h」包括「 bob.h「和」bob.h「包含」alice.h「,他們沒有包含警衛...... – 2009-10-31 10:39:56

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

#ifndef檢查給定令牌是否已經#defined先前在文件中或在包含文件;如果沒有,則包括它與結尾#else之間的代碼,或者如果不存在#else,則說明#endif聲明。 #ifndef通常用於通過在包含文件後定義標記並檢查未在該文件的頂部設置標記來使標頭文件具有冪等性。

#ifndef _INCL_GUARD 
#define _INCL_GUARD 
#endif 
+3

以下劃線開頭的標識符被保留;你不應該自己定義它們。使用類似'#ifndef H_HEADER_NAME'的東西。 – 2013-08-24 19:46:31

+5

我知道這是一箇舊評論,但實際上,下劃線限制僅適用於「外部標識符」 - 可能以編譯對象的符號表結束的標識符,即全局變量和函數名稱。它不適用於宏名稱。 – Stu 2014-05-15 13:05:19

+1

斯圖的評論是真的嗎?我剛剛閱讀https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier,現在我不太確定。 – Will 2017-06-28 08:23:50

2

這樣可以防止多次包含同一頭文件。

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

假設您已將此頭文件包含在多個文件中。所以第一次 __COMMON_H__沒有被定義,它會被定義幷包含頭文件。

下一次__COMMON_H__被定義,所以它不會再包含。

相關問題