#ifndef預編譯
需要注意的是,#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
相關文章
- js預編譯 --預編譯詳解四部曲JS編譯
- CSS預編譯器CSS編譯
- GCC編譯過程(預處理->編譯->彙編->連結)GC編譯
- stylus(css預編譯器)CSS編譯
- 對預編譯的理解編譯
- sqlserver2005預編譯SQLServer編譯
- JavaScript的預編譯過程分析JavaScript編譯
- dll預編譯提高webpack打包速度編譯Web
- css預編譯--sass基礎篇CSS編譯
- 編譯linux kernel預裝工具list編譯Linux
- EF Core預編譯模型Compiled Model編譯模型Compile
- 預編譯過程(AO+GO)編譯Go
- JavaScript預編譯原理, 引擎,作用域JavaScript編譯原理
- JS 預編譯程式碼例項分析JS編譯
- ifndef_ define_ endif 作用
- 你真的理解javascript中的預編譯麼?JavaScript編譯
- doxygen 宏定義/宏編譯/條件編譯/預處理/預編譯 不處理、忽略條件、分析所有條件、滿足所有條件的方法編譯
- CSS預編譯語言Less的用法總結CSS編譯
- JS----預編譯及變數提升詳解JS編譯變數
- CMakeLists.txt --- 匯入介面庫(預編譯庫)編譯
- MySQL中普通sql與預編譯sql 區別MySql編譯
- Vue 之青銅 I 晉級 [預先編譯]Vue編譯
- 【MySQL安裝】Linux下安裝MySQL(預編譯)MySqlLinux編譯
- Java編譯與反編譯Java編譯
- libusb android ndk編譯--編譯mipsAndroid編譯
- hadoop編譯—+2.x編譯Hadoop編譯
- N1064編譯鏈編譯編譯
- 編譯編譯
- Ubuntu 19.10將使用GCC 9作為預設編譯器UbuntuGC編譯
- 程式碼線上編譯器(上)- 編輯及編譯編譯
- hi3520d核心編譯編譯方法編譯
- Make編譯之編譯32bit ffmpeg編譯
- 開源編譯工具和編譯軟體編譯
- 編譯VIM編譯
- 編譯版本編譯
- 交叉編譯編譯
- 編譯googletest編譯Go
- 編譯宏編譯