[C] #Define 相關整理
--
Define為C語言中在預處理階段對程式碼進行字串替換
- 最簡單的define定義
就是文本替換,例如
#define MAXTIME 1000
一個簡單的MAXTIME就定義好了,它代表1000,如果在程式裡面寫
if (i<MAXTIME){………}
編譯器在處理這個程式碼之前會對MAXTIME進行處理替換為1000。
2. define的函式定義
#define max(x,y) (x)>(y)?(x):(y)
這個定義就返回兩個數中較大的那個。看似與函數一樣,但由於define指是作文本替換,所以有可能會衍伸出原本沒有預期的錯誤。例如
#define Add(a,b) a+b
若在程式中使用 c*Add(a,b)*d,原先預期的做法是 c*(a+b)*d,但實際上是c*a+b*d,這樣就會造成結果不同而出錯。解決的辦法是加上一個括號
#define Add(a,b) (a+b)
這樣就考以符合我們的預期。
在一個常見的例子是用define 定義宣告,例如
#define PINT (int *)
然後在程式碼的區域宣告
PINT a, b;
原本預期是宣告兩個 int*,也就是int *a, *b,然而使用define只會變成int *a, b,b就只會是int。這個情況比較好的做法是使用typedef。
typedef int* PINT;
3. 字串operator
stringizing operator (#)
程式碼中插入字串,例如
#define C(x) #xC(1)------〉"1"
charizing operator (#@)
程式碼中插入字元,例如
#define B(x) #@xB(1)------〉'1'
以及最常用的Token-Pasting operator (##)
用以連接字串的操作符
#define A(x) Var_##xA(1)------〉Var_1
最後還有換行符號 (/)
若MACRO需多行時,用換行符號換行
#define MACRO(arg1, arg2) do { /
/* declarations */ /
stmt1; /
stmt2; /
/* ... */ /
} while (0) /* (no trailing ; ) */
4. 條件編譯
在大規模的開發過程中,特別是跨平台和系統的軟件裡,define最重要的功能是條件編譯。
#ifdef DV22_AUX_INPUT
#define AUX_MODE 3
#else
#define AUY_MODE 3
#endif
#ifndef XXX … ( #else ) … #endif
可以在編譯的時候通過#define設置編譯環境
很常見的還有避免標頭檔重複定義
#ifndef _NAME_H
#define _NAME_H
//標頭檔案內容
#endif
例如專案中的 student.h 檔案可以做如下修改:
#ifndef _STUDENT_H
#define _STUDENT_H
class Student {
//......
};
#endif
雖然該專案 main.cpp 檔案中仍 #include 了 2 次 “student.h”,但鑑於 _STUDENT_H 只能定義一次,所以 Student 類也僅會定義一次。再次執行該專案會發現,其可以正常執行。
其他關鍵字如下:
//定義巨集
#define [MacroName] [MacroValue]
//取消巨集
#undef [MacroName]
//普通巨集
#define PI (3.1415926)
帶參數的巨集
#define max(a,b) ((a)>(b)? (a),(b))
這裡有個連結介紹foreach語法糖怎麼來的,來達到以下減化的功用:
int arr[] = {10, 20, 30, 40, 50};
foreach(int *v, arr) {
printf("%d ", *v);
}
Reference:
https://icodding.blogspot.com/2018/05/c-define.html
https://www.ithome.com.tw/voice/136689
https://tw511.com/a/01/3191.html