先贴代码:
#include<stdio.h>
#include<stdarg.h>
int sum(int,...);
int main(void){
printf("zhang%d",sum(4,1,2,3,4));
return 0;
}
int sum(int n,...){// n为参量的个数
va_list ap;// va_list类型代表一种数据对象,该对象用于存储参量列表中省略号部分代表的参量
int total = 0;
int i;
va_start(ap,n);// 把参数列表复制到va_list变量ap中
for(i = 0;i < n;i++){
total += va_arg(ap,int);// 参数分别为存储着变参的va_list对象和要处理的类型名。实际参数的类型必须与说明的类型相匹配,否则可能无法正常运行(因为不会进行自动转换)
}
va_end(ap);// 完成清理工作,释放动态分配的用于ap存放参数的内存。此后,只有用va_start重新对ap进行初始化,才能使用变量ap
return total;
}
运行结果输出zhang10
注意点:
1、包含进stdarg.h
2、使用方法
(1)在函数原型中使用省略号
(2)在函数定义中使用一个va_list类型的变量
(3)用宏va_start将该变量初始化为一个参数列表
(4)用宏va_arg访问这个参数列表
(5)用宏va_end完成清理工作
3、函数声明和函数定义中的第一个参数必须为int型的值,因为它指定变长参数的个数
4、每次调用va_arg都会从ap中取出并删除一个值
例如:
int x = va_arg(ap,int);
double y = va_arg(ap,double);
此时会从ap中删除它里面存储的前两项(从这儿也能看出,传实参时,多个实参之间的类型可以不同(例如传一个int一个double,然后像上面两行那样取),只要在取值的时候注意用和实参相同类型的变量进行取值即可)
正是由于va_arg删除其中的值后就无法再回退,所以保存va_list变量的副本很有用,这时可以使用va_copy,见下面代码
va_list ap;
va_list apcopy;
va_start(ap,n);
va_copy(apcopy,ap);// 把ap中的数据复制到apcopy中
int x = va_arg(ap,int);
double y = va_arg(ap,double);
此时虽然已经从ap中删除了两项,但是apcopy中前两项数据依然存在。