#ifndef預編譯

Sun_Shine_999發表於2018-04-07

需要注意的是,#ifndef起到的效果是防止一個原始檔兩次包含同一個標頭檔案,而不是防止兩個原始檔包含同一個標頭檔案。網上很多資料對這一細節的描述都是錯誤的。

事實上,防止同一標頭檔案被兩個不同的原始檔包含這種要求本身就是不合理的,標頭檔案存在的價值就是被不同的原始檔包含。

假如你有一個C原始檔,它包含了多個標頭檔案,比如標頭檔案A和標頭檔案B,而標頭檔案B又包含了標頭檔案A,則最終的效果是,該原始檔包含了兩次標頭檔案A。如果你在標頭檔案A裡定義了全域性變數或者結構體或者類型別(這是最常見的情況),那麼問題來了,編譯時會報大量的重複定義錯誤。

例如要編寫標頭檔案test.h
在標頭檔案開頭寫上兩行:

#ifndef _TEST_H
#define _TEST_H//一般是檔名的大寫

標頭檔案結尾寫上一行:

#endif

這樣一個工程檔案裡同時包含兩個test.h時,就不會出現重定義的錯誤了。

分析:
當第一次包含test.h時,由於沒有定義_TEST_H,條件為真,這樣就會包含(執行)#ifndef _TEST_H和#endif之間的程式碼,當第二次包含test.h時前面一次已經定義了_TEST_H,條件為假,#ifndef _TEST_H和#endif之間的程式碼也就不會再次被包含,這樣就避免了重定義了.
還是把標頭檔案的內容都放在#ifndef和#endif中吧。不管你的標頭檔案會不會被多個檔案引用,你都要加上這個。一般格式是這樣的:

#ifndef <標識>
#define <標識>
......
......
#endif

<標識>在理論上來說可以是自由命名的,但每個標頭檔案的這個“標識”都應該是唯一的。標識的命名規則一般是標頭檔案名全大寫,前面加下劃線,並把檔名中的“.”也變成下劃線,如:stdio.h

#ifndef _STDIO_H
#define _STDIO_H
......
#endif

相關文章