C 语言可变参数类型函数

    最常见的可变参数类型函数就是printf(const char* format,...),其特征是该函数的输入参数个数不固定,类型也不固定,很少场合需要设计可变参数类型的函数,但是需要可变参数类型函数的场合能够增加代码的灵活性,和可读性,本文着重介绍可变参数类型函数的设计方法。

 

1.预备知识

在头文件stdarg.h中定义了一个数据类型va_list,和三个宏定义来支持可变参数类型函数

typedef char *  va_list;  
#define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )
 
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) //第一个可选参数地址
 
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) //下一个参数地址
 
#define va_end(ap) ( ap = (va_list)0 ) // 将指针置为无效

    函数的执行是依靠栈来完成的,执行一个函数时,首先将参数列表压入栈(最后一个参数先入栈),然后是函数返回地址,最后是可执行代码。C语言使用指针来实现可变参数类型,读取可变参数的过程实际上就是,使用指针遍历堆栈(stack)中参数列表,从低地址到高地址挨个读取参数的过程。

    下面举例说明如何设计可变参数类型函数:

 

#include
#include 
#include 
/**
*任意个数整数求和
*/
int sum(int n,...)  
{  
    int i , sum = 0;
    va_list vap;  
    va_start(vap , n);//取得参数列表首地址
    for(i = 0 ; i < n ; ++i)  
        sum += va_arg(vap , int);//获取下一个参数地址
    va_end(vap);
    return sum;  
}

/**
*拷贝字符串
*/
void getname(const char* name,...)  
{  
	int i;
	char *e="red";
	char * pName = NULL;
	va_list vap;
	va_start(vap , name);//取得参数列表首地址
	pName = va_arg(vap , char *);//获取下一个参数地址
	strcpy(pName,e);
	va_end(vap);
}


int main(void)  
{  
	char colour[100];
	getname("None use" ,&colour);  

	printf("name:%s\n",colour);
	
	printf("sum:%d\n",sum(4,1,2,3,4));
	return 0;  
}  


 

你可能感兴趣的:(C/C++)