C可变参数详解及其函数设计
在stdarg.h文件中有如下几个宏定义:
#include <vadefs.h>
#define va_start _crt_va_start
#define va_arg _crt_va_arg
#define va_end _crt_va_end
#endif /* _INC_STDARG */
其定义在vadefs.h中分别为:
#define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) //第一个可选参数地址
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) //下一个参数地址
#define va_end(ap) ( ap = (va_list)0 ) // 将指针置为无效
在进程中,堆栈地址是从高到低分配的.当执行一个函数的时候,将参数列表入栈,压入堆栈的高地址部分,然后入栈函数的返回地址,接着入栈函数的执行代码,这个入栈过程,堆栈地址不断递减,一些***就是在堆栈中修改函数返回地址,执行自己的代码来达到执行自己插入的代码段的目的.
总之,函数在堆栈中的分布情况是:地址从高到低,依次是:函数参数列表,函数返回地址,函数执行代码段.
堆栈中,各个函数的分布情况是倒序的.即最后一个参数在列表中地址最高部分,第一个参数在列表地址的最低部分.参数在堆栈中的分布情况如下:
最后一个参数
倒数第二个参数
...
第一个参数
函数返回地址
函数代码段
代码示例:这里是一个可变参数的加法函数
#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>
/*功能:可变参数求和
*参数:numCount参数个数 ...可变求和参数
*返回值:参数相加的和
*/
int sum(int numCount,...)
{
int result = 0; //计算结果
va_list ap; //初始化指向可变参数列表的指针(typedef char* va_list)
va_start(ap,numCount); //将第一个可变参数的地址付给ap,即ap指向可变参数列表的开始
for(int i = 0;i<numCount;i++)
result += va_arg(ap,int); //得到第一个可变参数的值,并且ap指针上移一个_INTSIZEOF(int),即指向下一个可变参数的地址.
va_end(ap); //置空ap,即ap=(void *)0;
return result;
}
int main(void)
{
printf("20+15+3+8=%d\n",sum(4,20,15,3,8));
system("pause");
return 0;
}
转载于:https://blog.51cto.com/7212823/1202392
C可变参数详解及其函数设计相关推荐
- C语言传递可变参数详解
C语言传递可变参数详解 1.可变参数详解 在有些情况下,我们需要传递的参数的个数是可变的.C 语言为这种情况提供了一个解决方案,它允许定义一个函数,能根据具体的需求接受可变数量的参数.可以使编程更加的 ...
- java 可变参数 详解(通俗易懂)
目录 一.概述: 二.格式: 三.注意事项(使用规范): 四.代码演示: 演示规范①~③: 演示规范④: 演示规范⑤: 课堂练习: 代码演示: 输出结果: 五.英文版本讲解: 一.概述: java中, ...
- python可变参数教学,Python函数可变参数详解
在实际使用函数时,可能会遇到"不知道函数需要接受多少个实参"的情况,不过好在 Python 允许函数从调用语句中收集任意数量的实参. 例如,设计一个制作披萨的函数,我们知道,披萨中 ...
- C#FindWindowEx参数详解
FindWindowEx参数详解 本函数的其他内容在网络上都比较多,这里主要说一下它的参数设置和搜索结果的区别. 函数功能:在窗口列表中寻找与指定条件相符的第一个子窗口.该函数获得一个窗口的句柄,该窗 ...
- python函数中可变参数的传递方式是_详解Python函数可变参数定义及其参数传递方式...
Python函数可变参数定义及其参数传递方式详解 python中 函数不定参数的定义形式如下 1. func(*args) 传入的参数为以元组形式存在args中,如: def func(*args): ...
- python中可变参数*args传入函数时的存储方式为_python 中文读法详解Python函数可变参数定义及其参数传递方式...
Python函数可变参数定义及其参数传递方式详解 python中 函数不定参数的定义形式如下 1. func(*args) 传入的参数为以元组形式存在args中,如: def func(*args): ...
- 定义一个没有参数的函数、输出python3次_Python函数参数详解,三天让你掌握python,不再是小白
原标题:Python函数参数详解,三天让你掌握python,不再是小白 引言 随着程序功能的增多,代码量随之增大,此时仍不加区分地把所有功能的实现代码放到一起,将会使得程序的组织结构不清晰,可读性变差 ...
- python函数参数定义_Python函数定义及参数详解
函数定义 首先我们来创建一个函数,输出指定范围内的斐波拉契数列(Fibonacci series). #!/usr/bin/env python #coding=utf-8 ''' Created o ...
- ioctl函数详解(参数详解,驱动unlocked_ioctl使用、命令码如何封装)
@ioctl函数详解 一.ioctl函数的原型 在用户空间的函数原型 #include <sys/ioctl.h> int ioctl(int d, int request, ...); ...
最新文章
- 汽车行业要变天?数据告诉你,为什么说合资车企正在走向末路
- [译]发布ABP v0.19包含Angular UI选项
- redis、mysql、和php原生array数组效率对比
- 20190718每日一句
- 【车间调度】基于matlab遗传算法求解混合流水车间调度最优问题【含Matlab源码 901期】
- 程序设计语言及其文法
- abb的knx的数据库下载方法_ABB智能家居KNX方案.doc
- java 数字转换字母大写_大写字母或小写字母转换为数字
- 最好的降噪蓝牙耳机有哪些?目前最好的降噪蓝牙耳机推荐
- 吴恩达深度学习课程-Course 4 卷积神经网络 第一周 卷积神经网络编程作业(第一部分)
- jar包反编译工具(java-decompiler)
- 新⼀代USDP开源套件,可替代CDH的免费大数据套件平台及架构选型
- 开发利器IntelliJ IDEA—带你体验各种神奇操作
- C++学习日记#1.1——四元一次方程组进行Sor松弛迭代法求解(现已推向n元一次方程组进行Sor松弛迭代法求解)
- 浏览器修改主页不失效,打开浏览器弹出首页修改方法
- 白嫖freenom免费顶级域名
- C语言优惠套餐推荐系统
- DotNetCore CAP(分布式事务最终一致性)框架
- 【注意】加密与解密工具新年大礼包2007光盘提供下载
- 高通骁龙820A的硬件模块部分简介
热门文章
- nginx php unix负载,使用nginx配置多个php fastcgi负载均衡
- safari浏览器横屏怎么设置_Safari浏览器的几个小技巧你掌握了吗?
- 设计一个名为complex的类来表示复数_天线波束设计
- linux标准分发版的描述信息,如何查看Linux中系统版本信息
- 温度自动调节 c语言编写,室内温度自动调节控制系统课程设计(26页)-原创力文档...
- IIS服务器下做301永久重定向设置方法[图解]
- Locust接口性能测试
- 关于oracle中table函数的使用
- java 实现生产者-消费者模式
- 【commons】Bean工具类——commons-beanutils之BeanUtils