可变长参数函数
可变长参数函数的参数数量可变。如printf,scanf等函数都是可变长参数函数。
对C语言来说,实现可变长参数函数要用到三个宏:va_start(),va_end(),va_arg()和一个特殊类型va_list,他们被包含在stdarg.h中。
void va_start(va_list ap, T last):初始化函数
void va_end(va_list ap);释放ap所占的内存
type va_arg(ap,type);每次调用va_arg都会修改用va_list声明的对象,从而使该对象指向参数列表中的下一个参数;
举例说明:
#include<iostream>
#include<cstdarg>
int ADD(int num, ...);
int main()
{
int a = ADD( 3, 4, 5, 6);
std::cout << a << std::endl;
getchar();
}
int ADD(int num, ...)
{
va_list ap;
va_start(ap, num);
int sum = 0;
int temp;
for (int i = 0; i < num; i++)
{
temp = va_arg(ap,int);
sum += temp;
}
va_end(ap);
return sum;
}
对于可变长参数的实现的要求为:
1.C语言中,函数的参数都会传递到函数所对应的栈里面,而且参数是存放在连续的栈空间的。
2.对于参数进栈,C语言的顺序是从右往左进入栈,栈的增长方向是从上向下,所以参数的地址是从左往右顺序增长的。
验证这个想法,做如下程序,进行一般的可变参数函数的实现:
#include<iostream>
#include<cstdarg>
int ADD(int num, ...);
int main()
{
int a = ADD( 3, 4, 5, 6);
std::cout << a << std::endl;
getchar();
}
int ADD(int num, ...)
{
int sum = 0;
int *p=0;
int temp;
p = &num + 1;
for (int i = 0; i < num; i++)
sum += *(p++);
return sum;
}
得到的结果和上面一样。
注意点:
1.type va_arg(ap,type)
type不能是:
—— char、signed char、unsigned char
—— short、unsigned short
—— signed short、short int、signed short int、unsigned short int
—— float
在C语言中,调用一个不带原型声明的函数时,调用者会对每个参数执行“默认实际参数提升。可变长参数函数用...代替函数变量声明,所以会做这种参数提升。即:
float类型的实际参数将提升到double
char、short和相应的signed、unsigned类型的实际参数提升到int
版权声明:本文为博主原创文章,未经博主允许不得转载。

浙公网安备 33010602011771号