各類預處理指令的詳細解釋!!!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;