C/C++可变参数的使用详解
一.#的使用
定义:#就是用来提取生成字符串的。
#include <stdio.h>
//#就是用来提取生成字符串的
#define P(A) printf("%s:%d\n",#A,A)
int main(int argc, char *argv[])
{
int a = 1, b = 2;
P(a);
P(b);
P(a+b);
printf("Hello World!\n");
return 0;
}
输出结果:
二.##宏定义中用于连接前后两个宏变量
#include <stdio.h>
//宏定义连接前后两个宏变量的
#define LINKNAME(n) 2##n
#define LINKNAME2(m) a##m
int main(int argc, char *argv[])
{
int LINKNAME2(0) = 100;
printf("%d\n",LINKNAME2(0));//100
printf("%d\n",LINKNAME(4)); //24
return 0;
}
三.VA_ARGS,##__VA_ARGS__使用及其区别点
#include <stdio.h>
#define LOGI(...) printf(__VA_ARGS__)
#define LOGI2(format, ...) printf(format, __VA_ARGS__)
//##_VA_ARGS__,前面的##的作用就是当可变参数为0时,
//##可以将宏定义中逗号前面的format去掉的
#define LOGI3(format, ...) printf(format, ##__VA_ARGS__)
int main(int argc, char *argv[])
{
//第一种测试
LOGI("LOGI one args test\n");
LOGI("[%s:%d] LOGI more args test\n", __func__, __LINE__);
//第二种测试
//编译失败,扩展出来的只有一个参数,但是实际宏定义显式至少需要2个及其以上参数
//LOGI2("LOGI2 one args test\n");
LOGI2("[%s:%d] LOGI2 more args test\n", __func__, __LINE__);
//第三种测试
LOGI3("LOGI3 one args test\n");
LOGI3("[%s:%d] LOGI3 more args test\n", __func__, __LINE__);
return 0;
}
四.args的使用
args其实作用和__VA_ARGS__一样的
#include <stdio.h>
#define DEBUGLOG(format, args...) printf(format, ##args)
int main(int argc, char *argv[])
{
DEBUGLOG("ONE ARGS TEST\n");
DEBUGLOG("[%s:%d]more args test\n", __func__, __LINE__);
return 0;
}
五.实用举例
实际应用可能需要添加更多的调试信息,便于定位和排查错误。如定义模块名,文件名,函数名,行数等基本信息。
#include <stdio.h>
#include <time.h>
//带有更多的调试信息如时间,TAG,文件名和函数名与行数
#define TAG "MY_MODULE_NAME"
//第一种,精确到秒
/*
#define LOGPRINT(format, ...) do\
{\
time_t cur_time = time(NULL);\
struct tm *ptm = gmtime(&cur_time);\
printf("[%d-%02d-%02d %02d:%02d:%02d [%s] %s:%s:%d]"format, ptm->tm_year + 1900, ptm->tm_mon + 1, \
ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, TAG, __FILE__,__func__, __LINE__, ##__VA_ARGS__);\
printf("\n");\
}while(0)\
#endif
*/
//第二种方式 精确到毫秒
#define LOGPRINT(format, ...) do\
{\
char _format[256] = "";\
struct timeval tv;\
struct tm * tm;\
gettimeofday(&tv, NULL);\
tm = localtime(&tv.tv_sec);\
strftime(_format, sizeof(_format), "%c", tm);\
sprintf(_format+strlen(_format), " [%03d] [%s][%s:%s:%d]", (tv.tv_usec + 1)/1000,\
TAG, __FILE__, __func__, __LINE__);\
strcat(_format, format);\
printf(_format, ##__VA_ARGS__);\
printf("\n");\
}while(0)\
#define LOPRINT2(...) do\
{\
printf(__VA_ARGS__);\
printf("\n");\
}while(0)\
int main(int argc, char *argv[])
{
LOGPRINT("log print test");
LOGPRINT("[%s] more args test", "MORE_ARGS");
LOGPRINT2("LOGPRINT2 one argc test");
LOGPRINT2("[%s] more args test", "MORE_ARGS");
return 0;
}
第一种运行结果
第二种运行结果: