C/C++預處理指令#define,#ifdef,#ifndef,#endif…

 

各類預處理指令的詳細解釋!!!html

 

 

1.通常狀況下,源程序中全部的行都參加編譯。可是有時但願對其中一部份內容只在知足必定條件才進行編譯,也就是對一部份內容指定編譯的條件,這就是「條件編譯」。有時,但願當知足某條件時對一組語句進行編譯,而當條件不知足時則編譯另外一組語句。 ide

條件編譯命令最多見的形式爲: 

#ifdef 標識符 
程序段1 
#else 
程序段2 
#endif

它的做用是:當標識符已經被定義過(通常是用#define命令定義),則對程序段1進行編譯,不然編譯程序段2。 
其中#else部分也能夠沒有,即: 
#ifdef 
程序段1 
#denif

2.在頭文件中使用#ifdef和#ifndef是很是重要的,能夠防止雙重定義的錯誤。spa

如你在頭文件aaa.h中定義了一個類aaa以下:   
  class   aaa   
  {   
  };   
  若是兩次#include   "aaa.h"(不見得是直接,也有可能兩個不一樣的頭文件中都包含了這個頭文件)就會出錯,由於相同的類不能定義兩次。把aaa.h稍作修改:   
  #ifndef   _aaa_   
  #define   _aaa_   
  class   aaa   
  {   
  };   
  #endif  
code

補充:
在頭文件中使用的通常格式:   

#ifndef <標識>    ////頭文件開頭,名字是任意的,注意不要和其它頭文件衝突 
#define <標識>orm

...... 
......            //頭文件聲明 htm

#endif            //頭文件結尾blog

<標識>在理論上來講能夠是自由命名的,但每一個頭文件的這個「標識」都應該是惟一的。標識的命名規則通常是頭文件名全大寫,先後加下劃線,並把文件名中的「.」也變成下劃線,如:stdio.h ci

#ifndef _STDIO_H_ 
#define _STDIO_H_get

......it

#endif     

  就能夠避免這樣的問題。由於當你已經包含過這個文件,_aaa_就會有了定義,那麼#ifndef的條件爲假,就不會再執行後面的類定義了。 

3.#ifdef和#endif必須成對使用。   
  從理論上講能夠出如今任何地方(頭文件和實現文件中)  

4.在#ifndef中定義變量出現的問題(通常不定義在#ifndef中)。

#ifndef AAA
#define AAA
...
int i;
...
#endif
裏面有一個變量定義,在vc中連接時就出現了重複定義的錯誤,而在c中成功編譯。

結論:

(1).當你第一個使用這個頭的.cpp文件生成.obj的時候,int i 在裏面定義了當另一個使用這個的.cpp再次[單獨]生成.obj的時候,int i 又被定義而後兩個obj被另一個.cpp也include 這個頭的,鏈接在一塊兒,就會出現重複定義.

(2).把源程序文件擴展名改爲.c後,VC按照C語言的語法對源程序進行編譯,而不是C++。在C語言中,如果遇到多個int i,則自動認爲其中一個是定義,其餘的是聲明。

(3).C語言和C++語言鏈接結果不一樣,可能(猜想)時在進行編譯的時候,C++語言將全局變量默認爲強符號,因此鏈接出錯。C語言則依照是否初始化進行強弱的判斷的。(參考)

解決方法:

(1).把源程序文件擴展名改爲.c。

(2).推薦解決方案:
.h中只聲明 extern int i;在.cpp中定義

<x.h> #ifndef __X_H__ #define __X_H__ extern int i; #endif //__X_H__ <x.c> int i;

相關文章
相關標籤/搜索