定義

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)
C++ 可以美得令人不知所措 [source]

最後修改日期: 18 5 月 2020

留言

撰寫回覆或留言

發佈留言必須填寫的電子郵件地址不會公開。