天天看点

C语言不定参数个数,可变参数函数使用学习

stdarg.h提供了三个宏,书写可变参数函数可以用到

void va_start(va_list ap, last);

type va_arg(va_list ap, type);

void va_end(va_list ap);

上面宏的前缀va表示variable argument,即可变参数的意思。变量ap专门用来记录获取可变参数。下面依次介绍三个宏的意义和用法。

void va_start( va_list ap, last)

        last为函数形参中"..."前的最后一个形参名字,宏va_start用于根据last的位置(或指针)来初始化变量ap,以供宏ar_arg来依次获得可变参数的值。变量ap在被va_arg或va_end使用前,必须使用va_start初始化。

type va_arg(va_list ap, type)

       va_arg宏用来获得下一个参数的值,type为该参数的类型,它的参数ap必须被va_start初始化,通过该宏后,返回参数值并使用ap指向下一个参数,以供va_arg再次使用。如果没有下一个参数时调用va_arg或arg指定的类型不兼容时,会产生可知的错误。

void va_end(va_list ap)

         宏va_end与va_start必须要同一函数里面对称使用,调用va_start(ap,last)后ap得到初始化,在完成参数处理后,需要调用va_end(ap)来“释放”ap。 

简单示例:

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

void mySprintf(char *str, const char *p, ...)
{
	char *s;
	int i,count=0;
	char number[129]={0};
    
	va_list valist;//申请参数列表变量
	va_start(valist, p);//设置开始变量为传过来的参数p
	str[0] = 0;
	
	while(*p != '\0')
	{
		switch(*p)
		{
		case 's': 
			s = va_arg(valist, char*);//假设一进入就遇到s,va_arg(valist, char*)获取下一个参数是没有问题的,因为需要的就是下一个,而不是当前的参数
			strcat(str, s);
			break;
		case 'd':
			i = va_arg(valist, int);//获取下一个参数,变量类型在这里是确定的(自己指定的)
			strcat(str, itoa(i, number, 10));
			break;
		default:
			while(str[count] != '\0')count++;
			str[count] = *p;
			count = 0;
			break;
		}
		p++;
	}
	va_end(valist);//“释放”valist
}

int main()
{
	int a=12345;
	char *p = "abcdef";
	char str[100]={0};
	
	mySprintf(str, "p+a=sd", p, a);
	printf("%s\n", str);
	
	return 0;	
}
           

 运行结果:

C语言不定参数个数,可变参数函数使用学习

更多内容,参考资料:http://blog.csdn.net/hanchaoman/article/details/4153731

继续阅读