c语言可变参数va_list,va_start用法与分析

众所周知,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个.
c语言可变参数va_list,va_start用法与分析_第1张图片

函数分析:
1)首先在函数里定义一个 va_list型的变量 ,这里是arg_ptr,这个变量是 指向参数的指针
2)然后用 va_start宏初始化变量arg_ptr ,这个宏的 第二个参数是第一个可变参数的前一个参数 ,是一个固定的参数. 
3)然后用 va_arg返回可变的参数,并赋值给整数j. va_arg的第二个参数是你要返回的 参数的类型, 这里是int型.
4)最后用 va_end宏结束可变参数的获取 .然后你就可以在函数里使用第二个参数了.如果函数有多个可变参数的,依次调用va_arg获取各个参数.
c语言可变参数va_list,va_start用法与分析_第2张图片


虽然可以通过在堆栈中遍历参数列表来读出所有的可变参数,但是由于不知道可变参数有多少个,什么时候应该结束遍历
解决办法:
a.可以在第一个起始参数中指定参数个数,那么就可以在循环还中读取所有的可变参数;
b.定义一个结束标记,在调用函数的时候,在最后一个参数中传递这个标记,这样在遍历可变参数的时候,可以根据这个标记结束可变参数的遍历;

你可能感兴趣的:(c,宏,va_list)