2011年4月14日 星期四

[C++ 文章收集] C++中 #define的用法

轉載自 這裡
前言 :
這裡簡單說明了 #define 的幾種使用方法. 



簡單的define定義 :
#define MAXTIME 1000

一個簡單的MAXTIME就定義好了,它代表1000,如果在程序裡面寫 : 

int i = MAXTIME;


編譯器在處理這個代碼之前會對MAXTIME進行處理替換為1000。
這樣的定義看起來類似於普通的常量定義CONST,但也有著不同,因為define的定義更像是簡單的文本替換,而不是作為一個量來使用.

define的"函數定義" :
define可以像函數那樣接受一些參數,參考範例如下 :
#define max(x,y) (x)>(y)?(x):(y);

這個定義就將返回兩個數中較大的那個,看到了嗎? 因為這個"函數"沒有類型檢查,就好像一個函數模板似的,當然,它絕對沒有模板那麼安全就是了. 可以作為一個簡單的模板來使用而已. 但是這樣做的話存在隱患,例子如下 :
#define Add(a,b) a+b;

在一般使用的時候是沒有問題的,但是如果遇到如 : c * Add(a,b) * d 的時候就會出現問題, 代數式的本意是a+b然後去和c,d相乘,但是因為使用了define(它只是一個簡單的替換),所以式子實際上變成了:
c*a + b*d

另外舉一個例子 : 

#define pin (int*);
pin a,b;

本意是a和b都是int型指針,但是實際上變成int* a,b;
a是int型指針,而b是int型變量. 這是應該使用typedef來代替define,這樣a和b就都是int型指針了. 所以我們在定義的時候,養成一個良好的習慣,建議所有的層次都要加括號. 


宏的單行定義 :
考慮下列 #define 用法 : 

#define A(x) T_##x
#define B(x) #@x
#define C(x) #x
我們假設:x=1,則會有 : 
A(1)------>T_1
B(1)------>'1'
C(1)------>"1"

define的多行定義 :
define可以替代多行的代碼,例如MFC中的宏定義(非常的經典,雖然讓人看了噁心): 

  1. #define MACRO(arg1, arg2) do { \  
  2. /* declarations */ \  
  3. stmt1; \  
  4. stmt2; \  
  5. /* ... */ \  
  6. while(0/* (no trailing ; ) */  
關鍵是要在每一個換行的時候加上一個"\".

define的條件編譯 : 

  1. #ifdef WINDOWS  
  2. ......  
  3. ......  
  4. #endif  
  5. #ifdef LINUX  
  6. ......  
  7. ......  
  8. #endif  
可以在編譯的時候通過#define設置編譯環境.

如何定義宏、取消宏 : 

//定義宏
#define [MacroName] [MacroValue]
//取消宏
#undef [MacroName]
//普通宏
#define PI (3.1415926)
//帶參數的宏
#define max(a,b) ((a)>(b)? (a),(b))

關鍵是十分容易產生錯誤,包括機器和人理解上的差異等等.

條件編譯 :
#ifdef XXX…(#else) …#endif

例如 : 

#ifdef DV22_AUX_INPUT
#define AUX_MODE 3
#else
#define AUY_MODE 3
#endif
#ifndef XXX … (#else) … #endif

避免頭文件重複定義 :
由於頭文件包含可以嵌套,那麼C文件就有可能包含多次同一個頭文件,就可能出現重複定義的問題的. 通過條件編譯開關來避免重複引用, 例如 : 

#ifndef __headerfileXXX__
#define __headerfileXXX__

...
//文件內容
...
#endif

補充說明 :
楊舒凱 - C/C++ : 前置處理指令 
前處理指令(pre-processing instructions)顧名思義是編譯前的前處理,與程式邏輯無關,只是告知編譯器在開始編譯程式原始碼之前必須做的事情。在C/C++原始碼當中以#開始的指令都是編譯器(compiler)的前處理指令,這並不屬於 C++ 標準的一部分,所以各家的編譯器也會支援一些獨家的前處理指令,不過本篇要介紹的是所有編譯器都共通有的 #include、#define、#ifdef、#endif 指令,如下: 
#include <檔案>: 先把這個檔案合併進來。
#define: 把檔案裡面的字串先替換過。
#ifdef / #endif: 依據 #define 的現況排除某些程式碼

一些 C Macro 的技巧
C語言巨集定義技巧

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...