C++可变参数函数

  • Post author:
  • Post category:其他




举例

#include <stdarg.h>
#include <string>
using namespace std;

void va_add(int cnt, ...)
{
	va_list ap;
	va_start(ap, cnt);
	int sum = 0;
	for (int i = 0; i < cnt; ++i)
		sum += va_arg(ap, int);
	va_end(ap);
	printf("%d\n", sum);
}

int main()
{
	va_add(3, 1, 2, 3);		//6
	va_add(4, 1, 2, 3, 4);	//10
	return 0;
}



函数接口详解

带可变参数函数的实现使用了指针参数来解决参数的可变问题,指针参数随着其移动指向不同的参数,C语言的函数形参是从右向左压入堆栈的,以保证栈顶是第一个参数。

C语言标准库中头文件<stdarg.h>索引的接口包含了一组能够遍历变长参数列表的宏。



va_list(定义指针)

用来定义一个表示参数表中各个参数的变量,即定义了一个指向参数的指针, 用于指向可选的参数。



va_start(ap, args) (初始化指针)

使参数列表指针ap指向函数参数列表中的第一个可选参数,args是位于第一个可选参数之前的固定参数,或者说最后一个固定参数。通常用于指定可变参数列表中参数的个数。

如函数的声明是void va_test(char a, char b, char c, …),则它的固定参数依次是a,b,c,最后一个固定参数v为c,因此就是va_start(ap, c)。



va_arg(ap, type)

返回参数列表中指针ap所指的参数,返回类型为type。并使指针ap指向参数列表中下一个参数。返回的是可选参数,不包括固定参数。



va_end(ap)

清空参数列表,并置参数指针arg_ptr无效。

###3、一个实例my_printf

#define _CRT_SECURE_NO_WARNINGS
#include <cstdarg>
#include <cstdlib>
#include <cstdio>
#include <ctime>


size_t my_print(const char *fmt, ...)
{
	char buf[2000];
	time_t t;
	struct tm *p;
	time(&t);											//获取1970年1月1日到现在的秒数保存到t中
	p = gmtime(&t);										//将t中的秒数转换为实际日期的表示格式
	size_t len = sprintf(buf, "[%.4d-%.2d-%.2d %.2d:%.2d:%.2d]",
		p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);
	va_list argptr;
	va_start(argptr, fmt);
	size_t cnt = vsprintf(buf + len, fmt, argptr);
	len += cnt;
	va_end(argptr);
	puts(buf);
	return len;
}


int main()
{
	printf("%d", my_print("%s%s %s %s", "Wtf?", "What", "are you", "nong sha le!!!"));
	system("pause");
	return 0;
}

还有一种方法则是使用C++11中的可变参数模板(

函数模板

)也可以实现。



版权声明:本文为weixin_43971373原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。