#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
相關文章
- C語言的條件編譯#if, #elif, #else, #endif、#ifdef, #ifndefC語言編譯
- js預編譯 --預編譯詳解四部曲JS編譯
- CSS預編譯器CSS編譯
- GCC編譯過程(預處理->編譯->彙編->連結)GC編譯
- 對預編譯的理解編譯
- stylus(css預編譯器)CSS編譯
- JDBC預編譯語句JDBC編譯
- 關於預編譯頭 (轉)編譯
- sqlserver2005預編譯SQLServer編譯
- JavaScript的預編譯過程分析JavaScript編譯
- dll預編譯提高webpack打包速度編譯Web
- 預編譯過程(AO+GO)編譯Go
- JavaScript預編譯原理, 引擎,作用域JavaScript編譯原理
- css預編譯--sass基礎篇CSS編譯
- gcc 從語言編譯全過程 預處理---->編譯---->彙編----->連結GC編譯
- EF Core預編譯模型Compiled Model編譯模型Compile
- C++ 預編譯標頭檔案C++編譯
- 編譯linux kernel預裝工具list編譯Linux
- #ifndef/#define/#endif使用詳解
- ifndef_ define_ endif 作用
- 你真的理解javascript中的預編譯麼?JavaScript編譯
- javascript變數的宣告預編譯期間JavaScript變數編譯
- Xcode-新增pch預編譯檔案XCode編譯
- doxygen 宏定義/宏編譯/條件編譯/預處理/預編譯 不處理、忽略條件、分析所有條件、滿足所有條件的方法編譯
- c++進階(一)C語言條件編譯及編譯預處理階段C++C語言編譯
- Vue 之青銅 I 晉級 [預先編譯]Vue編譯
- MySQL中普通sql與預編譯sql 區別MySql編譯
- JS----預編譯及變數提升詳解JS編譯變數
- [C++]函式與編譯預處理(一)C++函式編譯
- [C++]函式與編譯預處理(二)C++函式編譯
- CSS預編譯語言Less的用法總結CSS編譯
- 關於JSP預編譯的中文問題JS編譯
- CMakeLists.txt --- 匯入介面庫(預編譯庫)編譯
- Java編譯與反編譯Java編譯
- 【MySQL安裝】Linux下安裝MySQL(預編譯)MySqlLinux編譯
- 如何預編譯 Android 模擬器專用核心編譯Android
- 《C++ Primer》筆記-#include,#ifndefC++筆記
- 編譯編譯