一个函数可以接受不定数的参数个数,这就是可变参数函数,比较常见的比如printf(),scanf();
printf(const char* format,…);
printf(“%d”,i);
printf(“%s”,s);
printf(“the number is %d,stirng is :%s”,i,s);
变量参数函数的简单实现:
#include<stdio.h>
#include<stdarg.h>
int simple(int num,...)
{
int i,result = 0;
va_list vl;
va_start(vl,num);
printf("num:%d, vl:%d\n",num,*vl);
for(i = 0; i < num - 1 ; i++)
{
result = va_arg(vl,int);
printf("in for result:%d ,*vl:%d\n",result,*vl);
}
va_end(vl);
return result;
}
int main()
{
int sum = simple(5,1,2,3,4,5);
if(0 == sum)
{
printf("simple failed\n");
}
else
{
printf("simple success! sum = %d\n",sum);
}
return 0;
}
结果如下:
exbot@ubuntu:~/wangqinghe/DeBug/20190702$ ./VA
num:5, vl:1020625376
in for result:1 ,*vl:1020625376
in for result:2 ,*vl:1020625376
in for result:3 ,*vl:1020625376
in for result:4 ,*vl:1020625376
simple success! sum = 4
sum.c
#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>
double add(int n,...)
{
//printf("add...\n");
int i = 0;
double sum = 0;
va_list argptr;
va_start(argptr,n); //初始化argptr
for(i = 0 ; i < n; i++) ////对每个可选参数,读取类型为int的参数
{
sum += va_arg(argptr,int); //累加到sum中
}
va_end(argptr);
printf("add_sum = %f\n",sum);
return sum;
}
int main(int argc,char **argv)
{
double sum = 0;
int *p = malloc(argc * sizeof(int));
int i;
for(i = 1; i < argc; i++)
{
p[i] = atoi(argv[i]);
printf("p[%d] = %d\n",i,p[i]);
}
sum = add(argc,p[1]);
printf("sum = %f\n",sum);
sum = add(argc,p[1],p[2]);
printf("sum = %f\n",sum);
sum = add(argc,p[1],p[2],p[3]);
printf("sum = %f\n",sum);
free(p);
return 0;
}
输出结果;
exbot@ubuntu:~/wangqinghe/DeBug/20190702$ ./sum 10 20 30
p[1] = 10
p[2] = 20
p[3] = 30
add_sum = 239745405.000000
sum = 239745405.000000
add_sum = 56.000000
sum = 56.000000
add_sum = 69.000000
sum = 69.000000
相关函数介绍:
可变函数列表的实现由几个宏组成的,在文件#include<stdarg.h>中。
va_list 定义某个变量,内核的定义如下:
typedef char *va_list; //字符指针类型
#ifndef __sparc__
#define va_start(AP, LASTARG) \
(AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))//ap指向下一个参数,lastarg不变
#else
#define va_start(AP, LASTARG) \
(__builtin_saveregs (), \
AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) //跳过下第一个参数,指向第二个参数内存地址
#endif
//对type向上取整 取int的整 4,然后乘上int整型4的倍数
#define __va_rounded_size(TYPE) \
(((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
// first=va_arg(args,int)
#define va_arg(AP, TYPE) \//ap指向下一个类型的参数
(AP += __va_rounded_size (TYPE), \//返回ap - sizeof(type)参数,即前一个参数
*((TYPE *) (AP - __va_rounded_size (TYPE))))
//对type向上取整 取int的整 4,然后乘上int整型4的倍数
#define __va_rounded_size(TYPE) \
(((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))