1.不借助函数库
void fun(int len,...){
int *p=&len;//获取第一个参数的指针
int i=0;
p++;
for(;i<len;i++){
printf("%d",*p);
}
}
fun(5,2,3,4,5,6);//第一个参数为输入的数值个数
2.借助函数库
#include <stdarg.h>
//int型例子
fun(5,2,3,4,5,6);【第一个参数为输入参数列表长度,便于获取参数长度,当然也可以不使用它(请看int型例子2)】
void fun(int len,...){
va_list ap;//新建参数列表信息数组 其实va_list实质为char *
va_start(ap,len);//初始化 获取len之前的参数(参数入栈是从右到左的,所以len是最后一个,也就是栈顶元素)
int val;
for(int i=0;i<len;i++){
val=va_arg(ap,int);//获取参数信息,第二个参数为参数列表的数据类型(注意:如果参数列表存'a'、'c'这种字符型右值,会被识别为int型的),返回值要与参数列表数据类型一致
printf("%d ",val);
}
va_end(ap);//ap置为NULL
}
//const char* 例子
fun("demo","we","are","programmer","") //我们依靠指针访问数据,所以故意留个"",目的是为了有个结束标志
fun(const char* flag,..){
va_list ap;
va_start(ap,flag);
char *s;
while(1){
s=va_arg(ap,char *);//省略const
if(strcmp(s,"")){ //比较获取的参数是否 为""(即为最后一个参数,这个作为结束标志)//既然用了strcmp就引个string.h的头吧
break;
}else{
printf("%s ",s);
}
}
}
//int型例子2【多余的例子可以不看】
#define END_TARGET 99999999 //比如设置一个END_TARGET作为结束标志,每次参数最后都带一个
fun(5,2,3,4,5,6,END_TARGET);【第一个参数为输入参数列表长度,便于获取参数长度,当然也可以不使用它(请看int型例子2)】
void fun(int start_target,...){ //不过此时start_target为废变量了
va_list ap;//新建参数列表信息数组 其实va_list实质为char *
va_start(ap,start_target);
int val;
while(1){
val=va_arg(ap,int);//获取参数信息,第二个参数为参数列表的数据类型(注意:如果参数列表存'a'、'c'这种字符型右值,会被识别为int型的),返回值要与参数列表数据类型一致
if(END_TARGET==val){ //取到结束标志就结束
break;
}
printf("%d ",val);
}
va_end(ap);//ap置为NULL
}
注意:参数列表可以不与va_start(参数1<va_list>,参数2<参数列表位置>)参数2不同类型
va_list函数的实质
#define va_list char *
#define va_start(p, first) (p = (va_list)&first + sizeof(first))
#define va_arg(p, next) (*(next*)((p += sizeof(next) ) - sizeof(next)))
#define va_end(p) (p = (va_list)NULL)
参考:
https://www.cnblogs.com/hanyonglu/archive/2011/05/07/2039916.html