可变参数列表
来源:互联网 发布:数据存储 信息安全 编辑:程序博客网 时间:2024/06/05 04:52
可变参数列表
C语言中,我们经常使用的printf函数,是可以输入任意多个参数的,而且当我们要写一个函数去求平均值或者其它,我们有时候要求两个数的平均值,有时候要求三个数的平均值,如果每次都封装一个函数,就很麻烦,所以C语言提供了可变参数
下面是一段求平均值的代码:
#include <stdio.h>#include <stdarg.h>int average(int n, ...) {va_list arg; int i = 0;int sum = 0;va_start(arg, n); for(i = 0; i<n; i++){sum += va_arg(arg, int);} return sum/n;va_end(arg); }可以看到其中有几个特别的地方,va_list,va_start,va_arg,va_end
打开头文件stdarg.h
#pragma once#endif#ifndef _INC_STDARG#define _INC_STDARG#if !defined(_WIN32)#error ERROR: Only Win32 target supported!#endif#include <vadefs.h>#define va_start _crt_va_start#define va_arg _crt_va_arg#define va_end _crt_va_end
可以看到我们使用的va_start,va_arg等都是封装好的宏,再打开<vadefs.h>查看宏具体的实现
typedef char * va_list;
va_list就是char*,代码中我们声明一个va_list类型的变量arg,用来访问参数列表的未确定部分
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )#define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )#define _crt_va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )#define _crt_va_end(ap) ( ap = (va_list)0 )
va_start是用来初始化arg变量,把arg变量初始化为可变参数部分的最后一个参数,从源码中可以看到ap也就是arg,直接跳到可变参数列表的第一个参数.具体什么意思,学识有限
va_arg的第一个参数是arg,第二个参数是下一个参数的类型,所以每次让ap向后跳一个类型的位置
va_end 感觉没什么用,可能只是结束标志
既然是个函数,在调用过程中就要形成栈帧结构,既然要形成栈帧结构,就要知道变量的位置,如果只有 average( ... ),你传入参数,临时参数该怎么形成呢?所以,可变参数列表就必须有一个参数,这样的话根据栈帧结构,我们就可以找到后面所有参数的地址
参数列表的限制
可以看出,可变参数列表是一个参数一个参数的访问,如果你想直接访问后面的元素是做不到的,但是你想访问到中途终止,这是可行的。
因为要找到其它的参数,所以参数列表中至少有一个参数,如果连一个参数都没有,就没法初始化
宏是无法直接判断实际参数的数量的
宏无法判断每个参数的类型
如果va_arg中指定了错误的类型,那么其后果是不可预测的
函数调用:
int main(){printf("%d\n",average(3, 10, 15, 20));return 0;}
运行结果:
阅读全文
0 0
- Java可变参数列表
- 可变参数列表
- 关于可变参数列表
- 可变参数列表
- c++ 可变参数列表
- 可变参数列表
- cstdarg可变参数列表
- 可变参数列表
- java可变参数列表
- 可变参数列表
- Java 可变参数列表
- 可变参数列表
- C可变参数列表
- 可变参数列表
- C可变参数列表
- 可变参数列表
- /可变参数列表
- 可变参数列表
- Python提取数字图片特征向量
- PJSIP
- 不到一年英伟达股价又翻番了,CFO说:感谢中国、感谢AI
- 自动化测试 -- 通过Cookie跳过登录验证码
- 如何解读羊毛出在了猪身上的保理业务?
- 可变参数列表
- (未开始)计算机视觉算法与应用_第五章_分割
- Android日记 五种点击事件
- 期刊发表要求一般有哪些
- Design Patterns in real life: Abstract Factory
- Ubuntu server 1404 SSH 远程搭建
- 船上线1
- 从远程PDB或者远程NO-CDB 克隆PDB
- 读大话设计模式