首页 > 编程语言 > 详细

C++中va_list, va_start, va_arg, va_end的基本用法

时间:2021-07-20 19:21:40      阅读:28      评论:0      收藏:0      [点我收藏+]

关于va_list, va_start, va_arg, va_end

由于在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中,所以用到可变参数的程序应该包含这个头文件)

 #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;
 }

There are four parts needed:

va_list: stores the list of arguments

va_start: initializes the list

va_arg: returns the next argument in the list

va_end: cleans up the variable argument list

Whenever a function is declared to have an indeterminate number of arguments, in place of the last argument you should place an ellipsis (which looks like ‘...‘), so, int a_function (int x, ...); would tell the compiler the function should accept however many arguments that the programmer uses, as long as it is equal to at least one, the one being the first, x

 

va_list is like any other variable. For example,

 va_list  a_list; 

va_start is a macro which accepts two arguments, a va_list and the name of the variable that directly precedes the ellipsis (...). So, in the function a_function, to initialize a_list with va_start, you would write va_start ( a_list, x );

va_arg takes a va_list and a variable type, and returns the next argument in the list in the form of whatever variable type it is told. It then moves down the list to the next argument. For example, va_arg ( a_list, double ) will return the next argument, assuming it exists, in the form of a double. The next time it is called, it will return the argument following the last returned number, if one exists.

To show how each of the parts works, take an example function:

 #include <cstdarg>
 #include <iostream>
 
 using namespace std;
 
 // this function will take the number of values to average
 // followed by all of the numbers to average
 double average ( int num, ... )
 {
   va_list arguments;                     // A place to store the list of arguments
   double sum = 0;
 
   va_start ( arguments, num );           // Initializing arguments to store all values after num
   for ( int x = 0; x < num; x++ )        // Loop until all numbers are added
     sum += va_arg ( arguments, double ); // Adds the next value in argument list to sum.
   va_end ( arguments );                  // Cleans up the list
 
   return sum / num;                      // Returns the average
 }
 int main()
 {
     // this computes the average of 13.2, 22.3 and 4.5 (3 indicates the number of values to average)
   cout<< average ( 3, 12.2, 22.3, 4.5 ) <<endl;
     // here it computes the average of the 5 values 3.3, 2.2, 1.1, 5.5 and 3.3
   cout<< average ( 5, 3.3, 2.2, 1.1, 5.5, 3.3 ) <<endl;
 }
 ?

 

C++中va_list, va_start, va_arg, va_end的基本用法

原文:https://www.cnblogs.com/YanAemons/p/15036139.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!