C中可變引數的巨集
阿新 • • 發佈:2018-12-30
在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
參考資料: