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,应该养成获取完参数表之后关闭指针的习惯。
三、示例
热门推荐
趵突泉的历史渊源与文化价值
儿童疫苗接种必读:流感疫苗对小孩的重要性探讨
香港含金量最高的四大专业
如何评价股票的风险与收益
注意了,几乎适合所有人吃的葡萄,却和这些“相克”!
JCC:皮下给药后英夫利昔单抗血清浓度升高与炎症性肠病患者的深度缓解密切相关
老慢支怎么治疗
大学生开学必备清单:生活用品与证件一文全览
关于颈动脉斑块,你需要知道的十件事
起始胰岛素治疗,需要掌握 3 个关键问题
"出售式重整"让"专精特新"企业资产"去壳重生"
飞机上可以带烟吗?飞机上明令禁止吸烟,为何还要配烟灰缸?知情人称:没它不能起飞
二月初三有讲究,推荐3道家常菜,吃出好彩头
“汉服传承发展不能只靠复制粘贴”
汉服行业两份重要文件发布,推动行业规范化标准化发展
客餐厅无主灯智能灯光设计 客餐厅无主灯好还是有主灯好
无抗产品认证技术规范:无抗鸡蛋介绍及认证流程
专家解答:鹅蛋和菠菜能否一起食用
鹅蛋和菠菜能一起吃吗?营养科医生的专业解答
如何利用堡垒机提升远程运维的安全性
如何确保软件技术架构图的清晰度
利用AI技术绘制架构图:方法与应用
哪些高血压患者适合看中医?中医师:有三类,具体如下
这会是中国足球的“一剂良药”吗?
古代汉语中的言辞之剑:探究古人的骂人艺术
如何摆脱牙齿敏感?改变刷牙方式/避免刺激性食物/定期检查等
基金投资全攻略:要点、策略与市场环境应对指南
吃枇杷能止咳吗?从枇杷果到枇杷膏的科学解析
枇杷干的功效与作用
明朝明英宗时期专政宦官王振人物生平经历简介