定義
define 是C語言中用來定義巨集(macro)的一個預處理器指示詞(preprocessor directive)。
其他的 Preprocess dircctive 還有 #if, #elif, #define…
Preprocessor directive 是在程式被編譯以前就先被載入的。 預處理程序指令用於提供通用指令或在程序內部使用的數人值。
1. 代表物件的語法 object-like macro
#define CName value
or
#define CName (expression)
範例:
#def NUM 17 // 數值
#define WEBSITE "catforcode.com" // 字串
#def HALF (NUM/17) // 敘述
2. 代表函數 function-like macro
返回兩個數中較大的那個(三元運算元)
#define max(x,y) (x)>(y)?(x):(y);
因為這個”函數”沒有類型檢查,就好像一個函數模板似的,當然,它絕對沒有模板那麼安全就是了。例如:
#define Add(a,b) a+b;
在一般使用的時候是沒有問題的,但是如果遇到如 :
c * Add(a,b) * d 的時候就會出現問題,
代數式的本意是a+b然後去和c,d相乘,但是因為使用了define(它只是一個簡單的替換),所以式子實際上變成了:ca + bd
解法就是加一個”(” “)”
#define Add(a,b) (a+b);
另外舉一個例子 :
#define point (int*); //變成pointer
point a,b;
本來想要的結果是a,b 都是int型別的pointer,
但結果是int* a, b。
因此要特別小心各種使用情況。
3. Define 多行
要在每一行的結束加上「\」。
#define dlist_push(type, list, item) do { \
if (!list) list = dlist_new(type); \
dlist_element(type) *node = dlistel_new(type); \
node->data = item; \
dlistel_link(list->tail, node); \
list->tail = node; \
if (!list->head) { \
list->head = node; \
} \
} while (0)
cf: dlist.h
備註:’##’operator的用法
我們使用#把巨集引數變為一個字串,用##把兩個巨集引數貼合在一起。例如以下範例:
#define STR(s) #s
#define CONS(a,b) int(a##e##b)
int main()
{
printf(STR(vck)); // 輸出字串"vck"
printf("%d\n", CONS(2,3)); // 2e3 輸出:2000
return 0;
}
C99規格書 cf6.10.3.3 The ## operator
C99的例子:
#define hash_hash # ## #
#define mkstr(a) # a
#define in_between(a) mkstr(a)
#define join(c, d) in_between(c hash_hash d)
char p[] = join(x, y); // equivalent to
// char p[] = "x ## y";
The expansion produces, at various stages:
join(x, y)
in_between(x hash_hash y)
in_between(x ## y)
mkstr(x ## y)
留言