c語言中ifndef和endif的用法

ifndef x //if not define的簡寫

  #define x   …  #endif
  這是宏定義的一種,它可以根據是否已經定義了一個變量來進行分支選擇,一般用於調試等等.實際上確切的說這應該是預處理功能中三種(宏定義,文件包含和條件編譯)中的一種—-條件編譯。 C語言在對程序進行編譯時,會先根據預處理命令進行“預處理”。C語言編譯系統包括預處理,編譯和鏈接等部分。
  #ifndef x //先測試x是否被宏定義過
  #define x
  程序段1 //如果x沒有被宏定義過,定義x,並編譯程序段1
  #endif

  程序段2 //如果x已經定義過了則編譯程序段2的語句,“忽視”程序段1。

  條件指示符#ifndef 的最主要目的是防止頭文件的重複包含和編譯。瞭解:條件編譯當然也可以用條件語句來實現。 但是用條件語句將會對整個源程序進行編譯,生成的目標代碼程序很長,而採用條件編譯,則根據條件只編譯其中的程序段1或程序段2,生成的目標程序較短。如果條件選擇的程序段很長,採用條件編譯的方法是十分必要的。

  #ifndef 標示1 //判斷”標示1”是否定義,如果被定義則返回假,如果沒有被定義則返回真。
  語句1 #ifndef 標示1
  語句2 #define 標示1
  語句3 #endif
  語句4 ……
  語句5 ……

  該段代碼意思是:如果標示1沒有被定義,則重定義標示1,即執行語句2、語句3、語句4、……;如果標示1已經被定義,則直接跳過語句2、語句3,直接執行語句4、語句5、……

  備註:#ifndef 和 #endif 要一起使用,如果丟失#endif,可能會報錯。

  千萬不要忽略了頭文件中的#ifndef,這是一個很關鍵的東西。比如你有兩個C文件,這兩個C文件都include了同一個頭文件。而編譯時,這兩個C文件要一同編譯成一個可運行文件,於是問題來了,大量的聲明衝突。
  還是把頭文件的內容都放在#ifndef和#endif中吧。不管你的頭文件會不會被多個文件引用,你都要加上這個。一般格式是這樣的:
  #ifndef <標識>
  #define <標識>
  ……
  ……
  #endif

<標識>在理論上來說可以是自由命名的,但每個頭文件的這個“標識”都應該是唯一的。標識的命名規則一般是頭文件名全大寫,前面加下劃線,並把文件名中的“.”也變成下劃線,如:stdio.h

  #ifndef _STDIO_H
  #define _STDIO_H
  ……
#endif
  在c語言中,對同一個變量或者函數進行多次聲明是不會報錯的。所以如果h文件裏只是進行了聲明工作,即使不使用# ifndef宏定義,一個c文件多次包含同一個h文件也不會報錯。

  但是在c++語言中,#ifndef的作用域只是在單個文件中。所以如果h文件裏定義了全局變量,即使採用#ifndef宏定義,一個c文件包含同一個h文件多次還是會出現全局變量重定義的錯誤。

  使用#ifndef可以避免下面這種錯誤:如果在h文件中定義了全局變量,一個c文件包含同一個h文件多次,如果不加#ifndef宏定義,會出現變量重複定義的錯誤;如果加了#ifndef,則不會出現這種錯誤。
  “ 條件編譯”命令允許對程序中的內容選擇性地編譯,即可以根據一定的條件選擇是否編譯。
  條件編譯的命令主要有以下幾種 :
  形式1
 #ifndef 標識符
  程序段 1
  #else
  程序段 2
  #endif

  它的作用是當 “ 標識符”已經由# d e f i n e定義過了。則編譯“ 程序段 2 ” 。 否則編譯“ 程序段 1 ” 。其中如果不需要編譯“ 程序段 2 ”。則上述形式可以變換 爲:

  #ifdef 標識符
  程序段 1
  #endif

  形式2
  #ifndef 標識符
  # define 標識符
  程序段 1
  #else
  程序段 2
  #endif

  它的作用是當 “ 標識符 沒有由# d e f i n e定義過。 則編譯“程序段 1”。否則編譯“程序段 2” 。同樣當無“ 程序段2 ”時。則上述形式變換爲:

  # ifndef 標識符
  # define 標識符
  程序段 1
  #endif
  
  形式3
  #if 表達式
  程序段 1
  #else
  程序段 2
  #endif

  它的作用是 當“表達式”值爲真時。編譯程序段1。否則則編譯程序段
  2。同樣 當無程序段 2時,則上述形式變換 爲 :
  #if 表達式
  程序段 1
  #endif

  以上三種形式的條件編譯預處理 結構都可以嵌套使用。 當#else後嵌套 # i f 時,可以使用預處理命令 #elif , 它相當於 #else#if。在程序中使用條件編譯主要是爲了方便程序的調試和移植。

2.在#ifndef中定義變量出現的問題(一般不定義在#ifndef中)。
#ifndef AAA
#define AAA

int i;

#endif
裏面有一個變量定義在vc中鏈接時就出現了i重複定義的錯誤,而在c中成功編譯。
原因:
(1).當你第一個使用這個頭的.cpp文件生成.obj的時候,int i 在裏面定義了。
當另外一個使用這個的.cpp再次[單獨]生成.obj的時候,int i 又被定義。
(2).把源程序文件擴展名改成.c後,VC按照C語言的語法對源程序進行編譯,而不是C++。在C語言中,若是遇到多個int i,則自動認爲其中一個是定義,其他的是聲明。

(參考解決方法:
(1).把源程序文件擴展名改成.c。
(2).推薦解決方案: .h中只聲明 extern int i;
在.cpp中定義
#ifndef X_H
#define X_H
extern int i;
#endif //X_H int i;
注意問題:變量一般不要定義在.h文件中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章