1. 程式人生 > >C中可變引數的巨集

C中可變引數的巨集

在C中,巨集的定義支援可變個數的引數,用三個點號來表示,和可變引數的函式定義是比較類似的。下面是一個例子:

 #define debug(format, ...) fprintf (stderr, format, __VA_ARGS__)

其中”…”就表示可變引數,可以是0個到多個,在編譯的時候__VA_ARGS__ 會被替換成相應的引數列表。

debug("%d apples\n", 10);

替換的結果就是:

fprintf(stderr, "%d apples\n", 10);

然而編譯下面的程式碼就會有問題:

debug("10 apples\n");

錯誤資訊如下所示:

這裡寫圖片描述

這是由於程式碼被擴充套件成了fprintf(stderr, "10 apples", ),後面多了一個逗號,通過把## 加在__VA_ARGS__ 前面就可以顯式讓前處理器去掉前面的逗號。

 #define debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__)

下面是一個完整的例子(來自msdn):

// variadic_macros.cpp
#include <stdio.h>

#define CHECK1(x, ...) if (!(x)) { printf(__VA_ARGS__); }
#define CHECK2(x, ...) if ((x)) { printf(__VA_ARGS__); }
#define CHECK3(...) { printf(__VA_ARGS__); } #define MACRO(s, ...) printf(s, ##__VA_ARGS__) int main() { CHECK1(0, "here %s %s %s", "are", "some", "varargs1(1)\n"); CHECK1(1, "here %s %s %s", "are", "some", "varargs1(2)\n"); // won't print CHECK2(0, "here %s %s %s", "are", "some", "varargs2(3)\n"
); // won't print CHECK2(1, "here %s %s %s", "are", "some", "varargs2(4)\n"); // always invokes printf in the macro CHECK3("here %s %s %s", "are", "some", "varargs3(5)\n"); MACRO("Today is %d-%d-%d\n", 2015, 11, 28); MACRO("hello, world\n"); return 0; }

在終端執行gcc test.cpp && ./a.out 可以得到下面的輸出:

here are some varargs1(1)
here are some varargs2(4)
here are some varargs3(5)
Today is 2015-11-28
hello, world

參考資料: