【转】C/C++中可变参数的详细介绍(va_list,va_start,va_arg,va_end)
可变参数的函数原理其实很简单,而va系列是以宏定义来定义的,实现跟堆栈相关.我们写一个可变函数的C函数时,有利也有弊,所以在不必要的场合,我们无需用到可变参数。如果在C++里,我们应该利用C++的多态性来实现可变参数的功能,尽量避免用C语言的方式来实现。
由于在C语言中没有函数重载,解决不定数目函数参数问题变得比较麻烦,即使采用C++,如果参数个数不能确定,也很难采用函数重载。对这种情况,提出了指针参数来解决问题。
如printf()函数,其原型为:
int printf( const char* format, ...);
它除了有一个参数format固定以外,后面跟的参数的个数和类型是可变的,例如我们可以有以下不同的调用方法:
printf( "%d ",i);
printf( "%s ",s);
printf( "the number is %d ,string is:%s ", i, s);
如何实现其功能?
我们需要以下几个宏定义:
(1)va_list
定义了一个指针arg_ptr, 用于指示可选的参数.
(2)va_start(arg_ptr, argN)
使
参数列表指针arg_ptr指向函数参数列表中的第一个可选参数,argN是位于第一个可选参数之前的固定参数,
或者说最后一个固定参数.如有一va函数的声明是void va_test(char a, char b, char c, ...),
则它的固定参数依次是a,b,c, 最后一个固定参数argN为c, 因此就是va_start(arg_ptr, c).
(3)va_arg(arg_ptr, type)
返回参数列表中指针arg_ptr所指的参数, 返回类型为type. 并使指针arg_ptr指向参数列表中下一个参数.返回的是可选参数, 不包括固定参数.
(4)va_end(arg_ptr)
清空参数列表, 并置参数指针arg_ptr无效.
(注:va在这里是variable-argument(可变参数)的意思. 这些宏定义在stdarg.h中,所以用到可变参数的程序应该包含这个头文件)
也需你现在还是不能理解,别着急,现在从一个实例着手.定义这么一个函数,函数的第一个参数是固定的,其余参数是可变的。定义为:
void simple_va_fun(int i,...); 其代码为:
#include <iostream> #include <string> #include <iostream> using namespace std; #include <stdarg.h> void simple_va_fun(int i, ...) { va_list arg_ptr; /// 定义可变参数指针 va_start(arg_ptr, i); /// i为最后一个固定参数 int j = va_arg(arg_ptr, int); //返回第一个可变参数,类型为int char c = va_arg(arg_ptr, char); ///返回第二个可变参数,类型为char va_end(arg_ptr); ///清空参数指针 printf("%d %d %c", i, j, c); return; } int main() { simple_va_fun(100); cout << endl; simple_va_fun(100, 200); cout << endl; simple_va_fun(100, 200, 'a'); cout << endl; system("pause"); return 0; }