C99中規定宏可以像函數一樣帶有可變參數,比如
#define LOG(format, ...) fprintf(stdout, format, __VA_ARGS__)
其中,...表示參數可變,__VA_ARGS__在預處理中爲實際的參數集所替換
GCC中同時支持如下的形式
#define LOG(format, args...) fprintf(stdout, format, args)
其用法和上面的基本一致,只是參數符號有變化
有一點需要注意,上述的宏定義不能省略可變參數,儘管你可以傳遞一個空參數,這裏有必要提到"##"連接符號的用法。
"##"的作用是對token進行連接,在上例中,format、__VA_ARGS__、args即是token,
"#"後面直接跟參數,相當於將參數外部加了一個雙引號“”,
宏定義中使用do while()可以避免warning,如果出現在判斷後的宏,可以保證作爲一個整體去實現。杜絕了多加一個分號的情況發生在代碼引入時候
如果token爲空,那麼不進行連接,所以允許省略可變參數(__VA_ARGS__和args),對上述變參宏做如下修改
#define LOG(format, ...) fprintf(stdout, format, ##__VA_ARGS__)
#define LOG(format, args...) fprintf(stdout, format, ##args)
/*
* va_list.cpp
*
* Created on: 2017年9月15日
* Author: guojing
*/
#include<iostream>
#include<stdio.h>
using namespace std;
#define MAX(a,b) a>b?a:b //普通帶參宏定義
//調試時輸出調試信息,正式發佈時則不輸出,在調試環境下,LOG宏是一個變參輸出宏,以自定義的格式輸出;在發佈環境下,LOG宏是一個空宏,不做任何事情。
#ifndef DEBUG
#define LOG(fmt,...) \
do \
{ \
printf(fmt,##__VA_ARGS__); \
}while(0) \//可變帶參宏定義, ...表示參數可變,__VA_ARGS__在預處理中爲實際的參數集所替換
#else
#define JUDGE_RETURN(CONDITION, RETURN) \
if (!(CONDITION))\
{\
return RETURN;\
}
#endif
int main()
{
int x=100,y=200;
int max=MAX(x,y);
cout<<max<<endl;
LOG("%s%s","hello","world");
return 0;
}