可变参数列表解析
来源:互联网 发布:手机尤克里里打谱软件 编辑:程序博客网 时间:2024/05/17 06:15
在函数的原型中,列出了函数期望接受的参数,但原型只能显示固定数目的参数。让一个函数在不同的时候接受不同数目的参数是不是可以呢?
首先我们来看看main函数的原型:
int main( int argc, char *argv[ ] , char *envp[ ] ){program-statements}
第一个参数: argc是个整型变量, 表示命令行参数的个数(含第一个参数) 。
第二个参数: argv是个字符指针的数组, 每个元素是一个字符指针, 指向一个字
符串。 这些字符串就是命令行中的每一个参数(字符串) 。
第三个参数: envp是字符指针的数组, 数组的每一个原元素是一个指向一个环境
变量(字符串) 的字符指针。
下面我们来看一个例子:
使用可变参数,实现函数求未知参数部分n个数的平均值。
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<stdarg.h>//可变参数列表是通过宏实现的,这些宏定义于stdarg.h头文件中int average(int n,...)//省略号提示此处可能传递数量和类型未确定的参数{ va_list arg; //相当于char*arg int i=0; int sum=0; va_start(arg,n); for(i=0;i<n;i++) { sum+=va_arg(arg,int); } va_end(arg); return sum/n;}int main(){ int ret=average(5, 1,2,3,4,5); printf("ret=%d\n",ret); return 0;
注:
stdarg.h宏是标准库的一部分,这个头文件声明了一个类型va_list和三个宏——va_start,va_arg和va_end。我们可以声明一个类型为va_list的变量,与这几个宏配合使用,访问参数的值。
对上面代码分析:
可变参数的实现过程是使用宏的封装。 只要完成替换, 我们就可以自行分析了。va_start(arg,n);转到定义#define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )替换后:#define va_start(arg,n) (arg=(va_list)&n+ _INTSIZEOF(n) //向上取整sum+=va_arg(arg,int);转到定义#define _crt_va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )替换后:sum+=(*(int*)((arg+=4)-4));
同理使用可变参数,实现函数求未知参数部分n个数中的最大值。
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<stdarg.h>int Max(int n,...){ int i=0; int max=0; int tmp=0; va_list arg; va_start(arg,n); for(i=0;i<n;i++) { if(max<(tmp=va_arg(arg,int))) { max=tmp; } } return tmp;}int main(){ int max=Max(5, 1,2,3,4,5); printf("%d\n",max); return 0;}
可变参数的限制
1,可变参数必须从头到尾逐个访问。 如果你在访问了几个可变参数之后想半途,终止, 这是可以的, 但是, 如果你想一开始就访问参数列表中间的参数, 那是不行的。
2,参数列表中至少有一个命名参数。 如果连一个命名参数都没有, 就无法使用va_start。
3,这些宏是无法直接判断实际存在参数的数量。
4,这些宏无法判断每个参数的是类型。
5,如果在va_arg中指定了错误的类型, 那么其后果是不可预测的。
阅读全文
0 0
- 可变参数列表解析
- 可变参数列表解析
- 可变参数列表解析
- 可变参数列表解析
- 可变参数列表解析
- 可变参数列表解析
- 可变参数列表解析
- 可变参数列表解析
- 可变参数列表解析
- 可变参数列表解析
- 可变参数列表解析
- 可变参数列表解析
- 可变参数列表解析
- 可变参数列表的解析
- 可变参数列表的解析
- 关于可变参数列表的解析
- C语言-可变参数列表的解析
- C语言中可变参数列表解析
- Hibernate(三)结构-基础语义和事务
- 我的python3基础笔记之 【定义函数】 03
- mysql:名次排名 (并列与不并列)
- 将大写字母转换成小写字母
- 微信小程序获取下标
- 可变参数列表解析
- Monkey and Banana HDU
- 在文字两边加两道线
- JetBrains全系列破解
- PLSQL查询结果复制时出现乱码的问题
- python 爬虫-1:下载网页源代码
- 高斯消元
- 省市区三级联动插件的使用
- Jenkins- 执行 PowerShell 命令