C++中va_list, va_start, va_arg, va_end的基本用法
关于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的基本用法的更多相关文章
- va_list/va_start/va_arg/va_end深入分析【转】
转自:http://www.cnblogs.com/justinzhang/archive/2011/09/29/2195969.html va_list/va_start/va_arg/va_end ...
- C++省略参数(va_list va_start va_arg va_end)的简单应用
原文参考自:http://www.cnblogs.com/hanyonglu/archive/2011/05/07/2039916.html #include <iostream> #in ...
- va_list/va_start/va_arg/va_end深入分析
http://www.cnblogs.com/justinzhang/archive/2011/09/29/2195969.html
- va_start,va_arg,va_end的使用
一.在C中,当我们无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表. void fun(...); void fun(parm_list,...); #include <stdi ...
- va_list、va_start和va_end使用
我们知道va_start,va_arg,va_end是在stdarg.h中被定义成宏的,由于1.硬件平台的不同 2.编译器的不同,所以定义的宏也有所不同. 在ANSI C中,这些宏的定义位于stdar ...
- va_start(),va_end()函数应用【转】
转自:http://www.cnblogs.com/gogly/articles/2416833.html 原理解释: VA_LIST 是在C语言中解决变参问题的一组宏,在<stdarg.h&g ...
- va_start(),va_end()函数应用
原理解释: VA_LIST 是在C语言中解决变参问题的一组宏,在<stdarg.h>头文件下. VA_LIST的用法: (1)首先在函数里定义一具VA_LIST型的变 ...
- 深入C语言可变参数(va_arg,va_list,va_start,va_end,_INTSIZEOF)
一.什么是可变参数 在C语言编程中有时会遇到一些参数个数可变的函数,例如printf(),scanf()函数,其函数原型为: int printf(const char* format,…),int ...
- OC可变參数的函数实现va_start、va_end、va_list的使用
一.简单介绍 我们常常在编程的时候看见类似这种代码,如图1.1 图1.1 或者是这种可变參数,如图1.2 图1.2 二.基本知识介绍 在学习怎样写这样的格式的函数前,先简介几个经常使用的宏: 下面摘自 ...
- va_start和va_end使用详解
本文主要介绍va_start和va_end的使用及原理. 介绍这两个宏之前先看一下C中传递函数的参数时的用法和原理: 1.在C中,当我们无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表 ...
随机推荐
- 修改yarn 缓存包 默认安装位置
yarn和npm一样,默认安装的全局包和缓存都在C盘里:npm的在:C:\Users\Administrator\AppData\Roaming\npmyarn的在:C:\Users\Admin\Ap ...
- GPS时钟之户外防水防雷细节
GPS时钟之户外防水防雷细节------专业LED时钟厂家![点击进入] GPS的脆弱性: 由于在GPS设计时,干扰环境下的工作能力不是优先考虑的因素,它只是作为一种导航的辅助工具,而不是用于精确制导 ...
- kettle连接mysql报Communications link failure
添加2个命名参数 1.autoReconnect=true 2.useSSL=false
- 重写antd组件样式
:global { .ant-select-selection-placeholder { color: #FFF; font-size: 14px; } .ant-select-selection- ...
- linux操作系统scp 命令远程复制文件
scp 复制文件到远程服务器,端口限制情况下 scp -P 22 文件名 远程服务器用户名@IP:/路径 scp -P 22 file user@IP:/file scp -P 复制文件到远程服 ...
- HTML笔记(一) HTML相关概念
一 HTML概述 1.HTML文档基本结构 先来看一个关于HTML的例子,里面包含了几个主要的HTML标签: <!DOCTYPE html> <html> <head&g ...
- PerfDog的使用教程
一.介绍: 移动全平台iOS/Android性能测试.分析工具平台,快速定位分析性能问题.PerfDog支持移动平台所有应用程序(游戏.APP应用.浏览器.小程序.小游戏.H5.后台系统进程等).An ...
- windows tips
u启动经典dos工具实现硬盘分区教程 https://jingyan.baidu.com/article/a3f121e4dbe55afc9052bbfe.html?st=2&net_type ...
- VSCODE C# 运行 找不到任务"BUILD"----C#常用命令
使用 Visual Studio Code 创建 .NET 类库 - .NET | Microsoft Docs 安装vscode.vscode c#相关拓展.MINIGW64 1.创建文件夹 2.用 ...
- CentOS7更改阿里源
阿里云yum源:1)备份当前yum源防止出现意外还可以还原回来cd /etc/yum.repos.d/cp /CentOS-Base.repo /CentOS-Base-repo.bak2)使用wge ...