众所周知,c没有c++的重载函数,所以函数有不定长度的参数会很难办。
不知你是否看到过这种定义函数的方式:int printf( const char* format, ...);
这是正确的定义,它定义了一个支持可变长度的printf函数。
printf("%d",i);
printf("%s",s);
printf("the number is %d ,string is:%s", i, s);
三种调用方式显示都是正确的。
但是我们怎么去得知,并且取printf函数...指代的参数呢??
首先介绍c中的几个宏: 它们在定义在stdarg.h中。
void va_start( va_list arg_ptr, prev_param );
type va_arg( va_list arg_ptr, type );
void va_end( va_list arg_ptr );
这里我们写一个函数,该函数至少有一个整数参数,第二个参数也是整数,是可选的.函数只是打印这两个参数的值.
void va_func(int i, ...) {
va_list arg_ptr;
int j=0;
va_start(arg_ptr, i);
j=va_arg(arg_ptr, int);
va_end(arg_ptr);
printf("%d %d\n", i, j);
}
void va_func(int i, ...);
调用:va_func(100); va_func(100,200);当然也可以不止两个参数,只是我们这里只打印了前2个.
函数分析:
1)首先在函数里定义一个
va_list型的变量
,这里是arg_ptr,这个变量是
指向参数的指针
.
2)然后用 va_start宏初始化变量arg_ptr ,这个宏的 第二个参数是第一个可变参数的前一个参数 ,是一个固定的参数.
3)然后用 va_arg返回可变的参数,并赋值给整数j. va_arg的第二个参数是你要返回的 参数的类型, 这里是int型.
4)最后用 va_end宏结束可变参数的获取 .然后你就可以在函数里使用第二个参数了.如果函数有多个可变参数的,依次调用va_arg获取各个参数.
2)然后用 va_start宏初始化变量arg_ptr ,这个宏的 第二个参数是第一个可变参数的前一个参数 ,是一个固定的参数.
3)然后用 va_arg返回可变的参数,并赋值给整数j. va_arg的第二个参数是你要返回的 参数的类型, 这里是int型.
4)最后用 va_end宏结束可变参数的获取 .然后你就可以在函数里使用第二个参数了.如果函数有多个可变参数的,依次调用va_arg获取各个参数.
虽然可以通过在堆栈中遍历参数列表来读出所有的可变参数,但是由于不知道可变参数有多少个,什么时候应该结束遍历
解决办法:
解决办法:
a.可以在第一个起始参数中指定参数个数,那么就可以在循环还中读取所有的可变参数;
b.定义一个结束标记,在调用函数的时候,在最后一个参数中传递这个标记,这样在遍历可变参数的时候,可以根据这个标记结束可变参数的遍历;