va_start和va_end使用介绍
创作时间:
作者:
@小白创作中心
va_start和va_end使用介绍
引用
CSDN
1.
https://blog.csdn.net/kupepoem/article/details/139487592
一、概述
在C语言编程中,函数的形式参数数目通常是确定的,调用时需要依次给出与形式参数对应的所有实际参数。但在某些情况下,希望函数的参数个数可以根据需要确定。例如,我们熟悉的printf()
、scanf()
和系统调用execl()
等函数。那么它们是如何实现的呢?
C编译器通常提供了一系列处理这种情况的宏,以屏蔽不同的硬件平台造成的差异,增加程序的可移植性。这些宏包括va_start
、va_arg
和va_end
等。在讲解这些宏之前,我们先了解一下调用函数时传入参数的处理过程。
在C语言中,当我们无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表:
void demo(...);
void demo(parm_list,...);
这种方式与我们以前认识的函数参数列表不同,但需要记住这是C语言中一种传参的形式,在后面我们就会用到它。
二、原理
函数参数是以数据结构栈的形式存取,从右至左入栈。
举个例子:
void demo(int x, float y, char z);
那么,调用函数的时候,实参 char z
先进栈,然后是 float y
,最后是 int x
,因此在内存中变量的存放次序是 x->y->z
。因此,从理论上说,我们只要探测到任意一个变量的地址,并且知道其他变量的类型,通过指针移位运算,则总可以顺藤摸瓜找到其他的输入变量。
下面是 <stdarg.h>
里面重要的几个宏定义:
假设有一个函数:void demo(char para, ...);
typedef char* va_list;
void va_start(va_list ap, para); /* ANSI version */
type va_arg(va_list ap, type);
void va_end(va_list ap);
va_list
是一个字符指针,可以理解为指向当前参数的一个指针,取参必须通过这个指针进行。
- 在调用参数表之前,定义一个
va_list
类型的变量(假设为ap
); - 应该对
ap
进行初始化,让它指向"可变参数表"里面的第一个参数,通过调用va_start
来实现的,第一个参数是ap
本身,第二个参数是在"变参表"前面紧挨着的变量即para
,也就是“...”之前的那个参数;可变参数表就是“...”,简称变参表。 - 若想获取参数,调用
va_arg
,它的第一个参数是ap
,第二个参数是要获取参数的类型,然后返回此类型的值,这两个类型必须一致,并把ap
的位置指向"变参表"的下一个变量位置; - 获取所有的参数之后,有必要将这个
ap
指针关掉,以免发生危险,调用va_end
方法将输入参数ap
置为NULL
,应该养成获取完参数表之后关闭指针的习惯。
三、示例
热门推荐
如何用数据库打标签
沉浸式展馆|中国科技馆产业创意焕新,沉浸营造“未来之城”
老人意外保险种类怎么选?一文详解各类保险特点与购买要点
十大经典教育游戏排行榜:寓教于乐的秘密武器
TES为何屡屡外战失利?这次0-2惨败KC再度刷新耻辱纪录
墓碑怎样选择
如何理解投机在投资中的作用?这种作用如何有效发挥?
燕云十六声基础操作按键
医药妙趣丨麦角新碱:其实我是坏孩子
动脉硬化早期发现可预防治疗
争四关键战,曼城能否复仇“海鸥”?
赫卡忒:少女,母亲,老妇
五险一金:内地社保有哪些保障?种类及缴费比例
Excel中计算中奖率的多种方法详解
农村房屋继承纠纷有哪些证据
Ubuntu系统如何连接手机上网:确认设备兼容性是关键
温州移动频现用户投诉,套餐升级降级问题引关注
数据分析中10种常见的可视化图例
如何有效地进行学习总结和复习
孩子不想上学?你的回应很重要
古时的东京,指的是现在的哪里?看完涨知识了!
中介违约如何解除合同?一文详解合同解除与违约责任
现代智能手机OLED屏幕技术前沿深度剖析及其烧屏现象详解
黑素细胞与黑色素细胞的区别是什么
黑素细胞的作用
痛经吃什么饭菜可以缓解疼痛
韩语学习高效指南:从入门到精通
如何查找出版后的书源码
握拳手抖是怎么回事?医生专业解答
浙江省缙云中学:百年名校的教育创新之路