http://www.uml.org.cn/c++/200902104.asp
#define 定義一個預處理巨集
#undef 取消巨集的定義
#include 包含檔案命令
#include_next 與#include相似, 但它有著特殊的用途
#if 編譯預處理中的條件命令, 相當於C語法中的if語句
#ifdef 判斷某個巨集是否被定義, 若已定義, 執行隨後的語句
#ifndef 與#ifdef相反, 判斷某個巨集是否未被定義
#elif 若#if, #ifdef, #ifndef或前面的#elif條件不滿足, 則執行#elif之後的語句, 相當於C語法中的else-if
#else 與#if, #ifdef, #ifndef對應, 若這些條件不滿足, 則執行#else之後的語句, 相當於C語法中的else
#endif #if, #ifdef, #ifndef這些條件命令的結束標誌.
defined 與#if, #elif配合使用, 判斷某個巨集是否被定義
#line 標誌該語句所在的行號
# 將巨集引數替代為以引數值為內容的字元竄常量
## 將兩個相鄰的標記(token)連線為一個單獨的標記
#pragma 說明編譯器資訊
#warning 顯示編譯警告資訊
#error 顯示編譯錯誤資訊
--------------------------------------
http://www.cnblogs.com/clover-toeic/p/3851102.html
2.3.2.4 可變引數巨集
...在C語言巨集中稱為Variadic Macro,即變參巨集。C99編譯器標準允許定義可變引數巨集(Macros with a Variable Number of Arguments),這樣就可以使用擁有可變參數列的巨集。
可變引數巨集的一般形式為:
#define DBGMSG(format, ...) fprintf (stderr, format, __VA_ARGS__) |
省略號代表一個可以變化的參數列,變參必須作為參數列的最右一項出現。使用保留名__VA_ARGS__ 把引數傳遞給巨集。在呼叫巨集時,省略號被表示成零個或多個符號(包括裡面的逗號),一直到到右括號結束為止。當被呼叫時,在巨集體(macro body)中,那些符號序列集合將代替裡面的__VA_ARGS__識別符號。當巨集的呼叫展開時,實際的引數就傳遞給fprintf ()。
注意:可變引數巨集不被ANSI/ISO C++所正式支援。因此,應當檢查編譯器是否支援這項技術。
在標準C裡,不能省略可變引數,但卻可以給它傳遞一個空的引數,這會導致編譯出錯。因為巨集展開後,裡面的字串後面會有個多餘的逗號。為解決這個問題,GNU CPP中做了如下擴充套件定義:
#define DBGMSG(format, ...) fprintf (stderr, format, ##__VA_ARGS__) |
若可變引數被忽略或為空,##操作將使編譯器刪除它前面多餘的逗號(否則會編譯出錯)。若巨集呼叫時提供了可變引數,編譯器會把這些可變引數放到逗號的後面。
同時,GCC還支援顯式地命名變參為args,如同其它引數一樣。如下格式的巨集擴充套件:
#define DBGMSG(format, args...) fprintf (stderr, format, ##args) |
這樣寫可讀性更強,並且更容易進行描述。
用GCC和C99的可變引數巨集, 可以更方便地列印除錯資訊,如:
1 #ifdef DEBUG 2 #define DBGPRINT(format, args...) \ 3 fprintf(stderr, format, ##args) 4 #else 5 #define DBGPRINT(format, args...) 6 #endif
這樣定義之後,程式碼中就可以用dbgprint了,例如dbgprint ("aaa [%s]", __FILE__)。
結合第4節的“條件編譯”功能,可以構造出如下除錯列印巨集:
1 #ifdef LOG_TEST_DEBUG 2 /* OMCI除錯日誌巨集 */ 3 //以10進位制格式日誌整型變數 4 #define PRINT_DEC(x) printf(#x" = %d\n", x) 5 #define PRINT_DEC2(x,y) printf(#x" = %d\n", y) 6 //以16進位制格式日誌整型變數 7 #define PRINT_HEX(x) printf(#x" = 0x%-X\n", x) 8 #define PRINT_HEX2(x,y) printf(#x" = 0x%-X\n", y) 9 //以字串格式日誌字串變數 10 #define PRINT_STR(x) printf(#x" = %s\n", x) 11 #define PRINT_STR2(x,y) printf(#x" = %s\n", y) 12 13 //日誌提示資訊 14 #define PROMPT(info) printf("%s\n", info) 15 16 //除錯定位資訊列印巨集 17 #define TP printf("%-4u - [%s<%s>]\n", __LINE__, __FILE__, __FUNCTION__); 18 19 //除錯跟蹤巨集,在待日誌資訊前附加日誌檔名、行數、函式名等資訊 20 #define TRACE(fmt, args...)\ 21 do{\ 22 printf("[%s(%d)<%s>]", __FILE__, __LINE__, __FUNCTION__);\ 23 printf((fmt), ##args);\ 24 }while(0) 25 #else 26 #define PRINT_DEC(x) 27 #define PRINT_DEC2(x,y) 28 29 #define PRINT_HEX(x) 30 #define PRINT_HEX2(x,y) 31 32 #define PRINT_STR(x) 33 #define PRINT_STR2(x,y) 34 35 #define PROMPT(info) 36 37 #define TP 38 39 #define TRACE(fmt, args...) 40 #endif
================================================================
上面都是摘抄,我遇到的問題是這樣的
debug(fmt, args...) debug_printf(__FUNCTION__,fmt,##args)
這樣是編不過的,
debug(fmt, ...) debug_printf(__FUNCTION__,fmt,##__VA_ARGS__)//buyao xiecuo xiahuaxian geshu
這樣才編過