#ifndef#define#endif防止頭文件重復包含, 你不是真的懂


注:以下所用環境皆為VS2005, 由於本人編程能力及表達能力有限, 大家有看不懂的地方可以多看幾遍,有錯誤地方請一定指出  

 

這里首先說明下幾點基礎知識, 相信大部分人對於以下幾點大部分都已經知道了, 你也可以直接跳到最后部分看#ifndef#define#endif的真正作用

  1.預編譯階段把所有#include ”***.h“ (“”與<>的區別這里就不說了)用***.h的內容來替換了, 所以之后就沒有.h了所有.h的內容都已經包含進了需要它們的.cpp中(注:該步個人認為是發生在預編譯階段) 

  2.生成最后的exe文件是由編譯、鏈接兩步完成的, 編譯是源代碼生成obj二進制目標文件的過程, 注意一個源代碼文件(指.cpp, 而非.h, .h已經被包含進.cpp中了)生成一個obj文件, 在VS2005中單獨編譯一個obj的方法是選中該.cpp文件ctrl+f7, 文章中以下所說的編譯皆按該方法執行而非F7, 由於編譯是獨立的, 所以在兩個獨立的編譯單元里是可以有重名的函數的, 例如a.cpp中可以有一個void fun(); b.cpp中可同時有一個void fun(); 這點十分重要, 大家可以試一下並且理解清楚

  3.編譯期間, 我們只要聲明了的東西就能使用, 而無需它的定義, 聲明可以重復, extern在編譯時是告訴該編譯單元該變量的定義在別的編譯單元里, 相當於聲明, 鏈接時, 定義在整個程序中有且僅有一份,  例如如下代碼, 編譯可通過, 但鏈接時失敗

  1. extern int a;  
  2. //extern double a;//錯誤, a只能有一個類型  
  3. extern int a;  
  4. extern void fun1(int a, int b);  
  5. extern void fun1(int a, int b);  
  6. extern void fun1(int a, int b, int c);//函數重載  
  7. void fun2();  
  8. void fun2(int a);//函數重載  
  9. void fun2()  
  10. {  
  11. }  
  12. int main()  
  13. {  
  14.     a = 100;  
  15.     fun1(200, 300);  
  16.     fun2();  
  17.     fun2(100);  
  18.     return 0;  
  19. }  
  20. void fun2();  

 

 

 

  4.我們從語法上來分析下#ifndef#define#endif(這點相信地球人都知道了)

  1. //-----a.h-----  
  2. #ifndef A_H_  
  3. #define A_H_  
  4. void fun();  
  5. #endif  

 

預編譯階段, 當第一次執行該段代碼(即#include "a.h",參見第一條)時, 由於我們並沒有宏定義A_H_, 所以會執行#define A_H_以及void fun()兩條語句, 第二次執行該段代碼時因為#ifndef A_H_為假就直接走到#endif后面也就等於該次#include "a.h"什么也沒做了

 

總結:

好了, 下面就我們以上所學的知識來總結一下, 來糾正大家一直以來對#ifndef#define#endif的誤解

當我們一個簡單的project中有三個文件main.cpp, a.cpp, a.h,而 main.cpp 和a.cpp分別包含了a.h, 在編譯階段, 兩個編譯單元是都會分別包含a.h的, 即使他們使用了#ifndef#define#endif, 這也是為什么當a.h被多個文件包含時我們不允許在a.h中定義變量及函數的原因, 因為在鏈接階段會出現重定義。 但是在a.h中定義一個static變量卻是允許的, 因為static變量是模塊性作用域, 就這個例子來說, 若我們在a.h中寫static int sss = 0;那么main.cpp與a.cpp使用的sss將為2個獨立的sss.

那么是否#ifndef#define#endif就沒用了呢, 大家可以想想, 當我們a.cpp中寫了多個#include "a.h"時, 如果我們使用了#ifndef#define#endif那么預編譯階段就只會包含一個a.h中的內容到a.cpp中, 你也許會說, 有誰會傻到在a.cpp中寫多個#include "a.h"呢, 那么請考慮稍微復雜點的情況, 當我們main.cpp中包含了a.h和b.h, 而a.h中我們又包含了b.h, 那么如果我們使用了#ifndef#define#endif則main.obj只會包含一份b.h

 

轉載地址:http://blog.csdn.net/q191201771/article/details/6399820


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM