int min_num(int val, ...)
{
va_list arg;
va_start(arg, val );
int min = va_arg (arg, int);
for (int i = 0; i < val-1; i++)
{
int tmp = va_arg (arg, int);
if (min>tmp)
min = tmp;
}
va_end(arg);
return min;
}
int main()
{
int ret=min_num(5,1,0,2,4,5);
printf( "%d\n", ret);
system( "pause");
return 0;
}
//注意可变参数列表至少要有一个参数,这是因为你要通过这个参数的地址才能访问后面的参数,而这个参数就叫做命名参数(也就是“ … ”前面的参数)
/va_list 是一个char 类型(typedef char va_list),声明一个char *类型的指针,便于向后访问.
//初始化arg,可以看到,va_start有两个参数,一个是va_list所声明的指针arg,另一个参数列表中第一个参数 val.
通过:#define _crt_va_start (ap,v) ( ap = (va_list) _ADDRESSOF(v) + _INTSIZEOF (v) )
看出,va_start的功能就是让指针arg向后偏移sizeof(val)个大小,即让arg指向参数列表中val之后的下一个参数的位置。(va_start(arg,val)实际上是让指针arg指向参数列表中第一个可变参数,所以va_start的第二个参数应该是“ … ”的前一个参数,因为本题中“ … ”前面只有一个参数val,所以va_start的第二个参数是val).
//va_arg(arg,int) 用来获取参数,即va_start(arg,int)表示的就是*arg;
通过:#define _crt_va_arg (ap,t) ( (t )((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
(ap += _INTSIZEOF(t)) - _INTSIZEOF(t) 所表达的意思可以分成两个语句:
第一个语句: ap+=_INTSIZEOF(t) 这时ap已经指向了下一个参数
第二个语句: ap-_INTSIZEOF(t) 整个表达式的值并没有保存,所以整个表达式*引用后指向的还是当前的值。
可以看到每当使用一次ap之后ap都向后偏移sizeof(int)个字节,指向下一个参数。
//这个也是一样,用来获取参数,但是到什么时候停下来呢???这时候val就派上作用,val代表 “…”中被传递过来实参的个数,例如在本题中,要找出5个数中最小值,val就是5;同理要是在100个数中找,val代表的是100
//因为arg是一个指针,所以在使用完后最好将它赋成空。
#define _crt_va_end (ap) ( ap = (va_list)0 )
va_list;是一个类型代表char *
va_start();初始化arg;实际上是:arg=&val+sizeof(aize_t val),让指针arg找到第一个可变参数
va_arg();获取下一个参数:就是引用*arg,用完之后再让arg加一(注意每使用一次va_arg(),arg都会自动指向下一个可变参数
va_end();将arg赋成0;把指针赋成0.
总结:可变参数列表通过参数之间的地址进行访问
可变参数列表的限制:
1、只能从第一个可变参数一次向后访问(这是移位他实际上是通过前一个参数的地址向后偏移找到下一个参数,依次向后递推着访问
2、因为可变参数列表是通过宏实现的,而宏无法判断参数的类型和可变参数的个数,所以我们必须使用命名参数。
例:模拟实现prinf函数,实现: print(arr, “s ccc.\n”,”hello” ,’b’,’i’,’t’);
[cpp] view plain copy
#include
#include
#include
char * print(char *arr,char *format, ...)
{
char *p = arr ;
va_list arg;
va_start(arg,format );
while (*format )
{
if (*format == 's')
{
char *p3 = va_arg (arg, char *);
while (*p3)
{
*p++=*p3++;
}
p--;
}
else if (*format == 'c')
*p = va_arg(arg, char );
else
*p= *format;
format++;
p++;
}
*p = '\0';
va_end(arg);
return arr ;
}
int main()
{
char arr[100];
print(arr, "s ccc.\n","hello" ,'b','i','t');
printf( "%s",arr);
system( "pause");
return 0;
}