1. 概述

va_list 是在 C 语言中引入解决变参问题的一组宏,变参问题是指参数的个数不定或者每个参数的类型不同。

头文件:
#include <stdarg.h>

2. 使用步骤

va_list 是一个字符指针类型,在代码中可以理解成当前参数集的指针,下面是几个与 va_list 相关常见的函数

1. typedef char* va_list;2. void va_start (va_list ap, prev_param);$ 对 va_list 进行初始化,将 ap 指针指向参数列表中的第一个参数$ 第一个参数是 va_list 指针,第二个参数变参前面紧挨的一个变量,即"..."之前的那个参数3. void va_end(va_list ap);$ 释放指针,将输入的参数 ap 置为 NULL。$ 通常va_start和va_end是成对出现。4. type va_arg(va_list ap, type); $ 获取参数值,第一个参数 ap 指针,第二个参数是要获取的值类型$ 返回这个指定类型的值,然后把 ap 指针位置指向变参表中下一个参数的位置

以一个例子进行说明

(1) 当出现无法列出所有传递参数数目和类型的时候,用省略号指定参数列表

void PrintInt (int cnt, ...)

(2) 使用 va_list 获取参数并进行处理
- 定义一个 va_list 类型的变量,va_list 类型变量定义为 ap
- 调用 va_start,对 ap 进行初始化,让它指向可变参数表里面的第一个参数
- 使用 va_arg 获取参数,并使用参数
- 获取所有的参数之后,将 ap 指针关掉

void PrintInt(int cnt, ...)  { va_list ap;int value;va_start(ap, cnt);for (int i = 0; i < cnt; i++) {value = va_arg(ap, int);printf("%d\n", value); }va_end(ap);
}

(3) 调用变参函数

int main(void) {PrintInt(4, 1, 2, 3, 4);
}

输出结果为:

1
2
3
4

函数参数的传递原理

这里说明一下输出打印结果的原因,涉及函数参数的传递原理。

va_list 的实现原理过程中函数参数是以栈的形式存取,从右至左入栈。

参数的内存存放格式:参数存放在内存的堆栈段中,在执行函数的时候,从最后一个开始入栈。因此栈底高地址,栈顶低地址。

使用 va_arg 函数取出的时候从栈顶开始取,所以上面的例子中取出的第一个参数是 1.

valist:解决变参问题相关推荐

  1. 【valist】c语言可变参数宏

    va_list 是C语言中解决变参问题的一组宏. 1.API介绍: 头文件: [cpp]  view plain copy print ? #include <stdarg.h> 下面是实 ...

  2. 转载--va_list

    链接:va_list百科 1:概述 VA_LIST 是在c语言中解决变参问题的一组宏,所在头文件:#include <stdarg.h> 2:成员 #ifdef _M_ALPHA type ...

  3. va_list和vsnprintf、getopt

    原理解释: VA_LIST 是在C语言中解决变参问题的一组宏,在<stdarg.h>头文件下. VA_LIST的用法:            (1)首先在函数里定义一具VA_LIST型的变 ...

  4. va_start(),va_end()函数应用

    原理解释: VA_LIST 是在C语言中解决变参问题的一组宏,在<stdarg.h>头文件下. VA_LIST的用法:             (1)首先在函数里定义一具VA_LIST型的 ...

  5. 对va_list; va_start ; va_end ;vsprintf理解(转)

    以下为转载内容: 1 int printf(const char* fmt, ...) 2 { 3 va_list args; 4 int i; 5 //1.将变参转化为字符串 6 va_start( ...

  6. 【C++】Web服务器项目所用到的函数详解

    文章目录 1 Web服务器端监听 1.1 socket()函数 1.2 struct sockaddr和struct sockaddr_in结构体(INADDR_ANY) 1.3 bzero()函数 ...

  7. C函数参数中的三个点

    原文链接一:http://hi.baidu.com/wjun520/blog/item/1678a11da07fe68086d6b653.html C++中有函数重载这种方法,以供我们调用时要可以不确 ...

  8. CS:APP 计算机系统 课程大作业

    学号:120L022004 目  录 第1章 概述... - 4 - 1.1 Hello简介... - 4 - 1.2 环境与工具... - 4 - 1.3 中间结果... - 5 - 1.4 本章小 ...

  9. C++实现高并发Web服务器

    1.服务器编程基本框架 服务器程序种类繁多,但其基本框架都是一样的,它们的不同之处在于逻辑处理.如图所示是服务器的基本框架. 该图既能用来描述一台服务器,也能用来描述一个服务器机群.如下是各个部件的含 ...

最新文章

  1. 编译cegcc 0.59.1
  2. 3、使用Statement接口实现增,删,改操作
  3. .net 访问mysql链接池_c# – .NET SqlConnection类,连接池和重新连接逻辑
  4. Java多线程初学者指南(12):使用Synchronized块同步变量
  5. 捷信达会员管理系统SQL语句相关
  6. 使用harbor搭建docker镜像私有仓库
  7. 史上最全天气预报接口,含各类数据接口,历史数据,天气大数据,雷达云图、6要素数据,格点数据等
  8. 原生JS实现的跳一跳小游戏完整实例
  9. 问题 J: 爱吃榴莲的LZY
  10. VMware ESXi添加NVMe硬盘扩容
  11. ubuntu启动报错 hardware error cpu 0 machine check 0 Bank 6、ACPI BIOS Error (bug)Could not resolve symbol
  12. python摄像头人脸识别小程序 开门,OpenCV3-Python人脸识别方法—基于摄像头
  13. MacBook更新系统空间不足/无限重启/无法退出更新程序
  14. 利用C,C++的宏,获取变量名!
  15. 读研的那些事儿(三)
  16. Appium基础篇11-元素操作之点击和输入
  17. byvoid阿里第二弹:不是技术牛人,如何拿到国内IT巨头的Offer
  18. 揭秘直销软件系统PHP源码开发价格与奖金制度设计方案
  19. SVN代码统计工具statsvn
  20. RTM CU CTP

热门文章

  1. 英语学习——新婚贺词
  2. 可视化项目使用vw/vh布局进行适配
  3. SAP订单状态最详细的解释
  4. PHP preg_match()函数
  5. 微信小程序手机号码如何进行解密
  6. python-opencv 读取摄像头并保存为.mp4视频 及 VideoCapture()的使用
  7. 转录组分析 - 使用 sratoolkit docker镜像 - 目录挂载 - docker中的路径和linux中的路径
  8. 分布式优化算法学习(一)
  9. 与北京相比较而言,杭州能不能挺进“一线”,还得看未来科技城---云城,第二机场入住云城周边是神助攻
  10. 基于浏览器的http普通请求与ajax请求