宏定義中的一些問題

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;
}






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章