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

C/C++常見的預處理指令如下:

  1. #空指令,無任何效果
  2. #include包含一個源代碼文件
  3. #define定義宏
  4. #undef取消已定義的宏
  5. #if如果給定條件爲真,則編譯下面代碼
  6. #ifdef如果宏已經定義,則編譯下面代碼
  7. #ifndef如果宏沒有定義,則編譯下面代碼
  8. #elif如果前面的#if給定條件不爲真,當前條件爲真,則編譯下面代碼
  9. #endif結束一個#if……#else條件編譯塊
  10. #error停止編譯並顯示錯誤信息

1.比如你有兩個C文件,這兩個C文件都include了同一個頭文件。而編譯時,這兩個C文件要一同編譯成一個可運行文件,於是問題來了,大量的聲明衝突。 還是把頭文件的內容都放在#ifndef和#endif中吧。
不管你的頭文件會不會被多個文件引用,你都要加上這個。

一般格式是這樣的:

#ifndef <標識>

#define <標識>

......

......

#endif <標識>

 

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

#ifndef _STDIO_H_

#define _STDIO_H_

......

#endif

例1:

#ifndef _APPDEFS_H_

#define _APPDEFS_H_

#define WeakSelf __weak __typeof(self) weakSelf = self

#define USE_NSLOG

#ifdef USE_NSLOG

# define NSLog(...) NSLog(__VA_ARGS__)

# define _Log(s, ...)    NSLog(s, ##__VA_ARGS__)

#else

# define NSLog(...) {}

# define _Log(s, ...)    ((void) 0)

#endif

例2:

#ifdef __OBJC__

#import <UIKit/UIKit.h>

#import <Foundation/Foundation.h>

#endif

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

#ifndef AAA
#define AAA
...
int i;
...
#endif
裏面有一個變量定義在vc中鏈接時就出現了i重複定義的錯誤,而在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中定義
#ifndef __X_H__
#define __X_H__
extern int i;
#endif //__X_H__ int i;
注意問題:變量一般不要定義在.h文件中。

 

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