可變參數宏定義
C99編譯器標准允許你可以定義可變參數宏(variadic macros),這樣你就可以使用擁有可以變化的參數表的宏。可變參數宏就像下面這個樣子:
#define dbgprint(...) printf(__VA_ARGS__)
缺省號代表一個可以變化的參數表。使用保留名 __VA_ARGS__ 把參數傳遞給宏。當宏的調用展開時,實際的參數就傳遞給 printf()了。
可變參數宏不被ANSI/ISO C++ 所正式支持。因此,你應當檢查你的編譯器,看它是否支持這項技術。
用GCC和C99的可變參數宏, 更方便地打印調試信息
#ifdef DEBUG #define dbgprint(format, ...) \ fprintf(stderr, format, __VA_ARGS__) #else #define dbgprint(format, ...) #endif
在標准C里,你不能省略可變參數,但是你卻可以給它傳遞一個空的參數。例如,下面的宏調用在ISO C里是非法的,因為字符串后面沒有逗號:
dbgprint ("A message")
GNU CPP在這種情況下可以讓你完全的忽略可變參數。在上面的例子中,編譯器仍然會有問題(complain),因為宏展開后,里面的字符串后面會有個多余的逗號。
為了解決這個問題,CPP使用一個特殊的'##'操作。書寫格式為:
#define dbgprint(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
這里,如果可變參數被忽略或為空,'##'操作將使預處理器(preprocessor)去除掉它前面的那個逗號。
如果你在宏調用時,確實提供了一些可變參數,GNU CPP也會工作正常,
它會把這些可變參數放到逗號的后面。象其它的pasted macro參數一樣,這些參數不是宏的擴展。
/* C語言 宏定義之可變參數 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define MDEBUG #ifdef MDEBUG #define TEST_LOG(format,...) fprintf(stderr, format, ##__VA_ARGS__) #else #define TEST_LOG(format,...) #endif int test() { int num = 10; TEST_LOG("my num is %d .\n", num); return num; } int main() { test(); printf("--------ok-------\n"); return 0; }