c语言变参宏和利用变参宏的一些简单的打印实现

一些函数(如printf)接受数量可变的参数。stdvar.h头文件提供了工具,让用户自定义带可变参数的函数。通过把宏参数列表中最后的参数写成省略号(即3个点...)来实现这一功能。这样,预定义宏__VA_ARGS__可用在替换部分中,表明省略号代表什么。举个例子:

#define LOG(...) printf(__VA_ARGS__)
int main()
{
	LOG("hello\n"); // __VA_ARGS__== "hello\n"
	LOG("%s\n", "hello"); // __VA_ARGS__== "%s\n", "hello"
}

上面的例子其实就相当于将LOG替换成printf,但实际上可以增加一些额外的信息,在程序中让打印信息更全。接下来介绍几种简单打印实现,并介绍可变参数

1、纯使用宏的实现

#define print_out(format, ...)					\
{												\
	time_t t = time(NULL);          \
	struct tm ttt = *localtime(&t);\
	fprintf(stdout, "["__FILE__"][%4d-%02d-%02d %02d:%02d:%02d][%s:%d] " format "\n",                     \
            ttt.tm_year + 1900, ttt.tm_mon + 1, ttt.tm_mday, ttt.tm_hour,        \
            ttt.tm_min, ttt.tm_sec, __FUNCTION__ ,  __LINE__, ##__VA_ARGS__);                            \
}

这个在之前的博客中已经写过了,但是这里详细的介绍一下。这是一个包含时间,文件名,函数名,行号的打印宏。其中,各个宏的含义如下

__FILE__:表示当前源代码文件名的字符串字面量(可以直接使用字符串拼接,如上例所示)

__FUNCTION__:函数名

__LINE__:行号

##__VA_ARGS__:__VA_ARGS__的函数介绍过了,宏前面加上##的作用在于,当可变参数的个数为0时,这里的##起到把前面多余的","去掉的作用,否则会编译出错

举个例子,

#include <stdio.h>
#include <stdarg.h>

#define LOG(format, ...)  do{printf(format, __VA_ARGS__);}while(0)
int main()
{
    LOG("hello\n");
}

这样使用gcc编译会失败,但是使用vs2013编译好像是没问题的。但是如果加上##,gcc编译就可以成功。

2、使用宏和函数的实现

#include<stdio.h>
#include <stdarg.h>
#define LOG_INFO(...) \
	log_info(__FILE__, __FUNCTION__, __LINE__, \
	__VA_ARGS__)

void log_info(const char *file, const char *func, long line,
	const char *format, ...)
{
	va_list args;//声明一个存储参数的对象
	char buf[2048] = { 0 };
	va_start(args, format); //把args初始化为参数列表
	vsprintf(buf, format, args);
	printf("[%s][%s:%d] " "%s", file, func, line, buf);
	va_end(args);	//清理工作
}

在该例子中,使用了可变参数。使用变参宏,用法相对比较复杂,必须按如下步骤进行:

  1. 提供一个使用省略号的函数原型;
  2. 在函数定义中创建一个va_list类型的变量;
  3. 用宏把该变量初始化为一个参数列表;
  4. 用宏访问参数列表;
  5. 用宏完成清理工作。

当然,也可以使用纯函数的,或者也可以将标准输出流改为文件流,向指定的文件输出打印信息,还可以按照自己的需求增加其他的内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值