浅析可变参数列表
来源:互联网 发布:泼墨字体生成软件 编辑:程序博客网 时间:2024/06/07 11:27
一般的函数在传参时只能传一个或两个甚至多个参数,但其前提是参数的个数必须是固定不变的。printf()函数和scanf()函数的参数却是可变的。在printf()函数中,它所传的参数是由标准化格式输出的类型决定。例:
int main(){ printf("%s\n", "hello world"); printf("%s%s%c", "hello ", "worl", 'd'); system("pause"); return 0;}
这段代码中,第一个printf有一个%s代表其参数只有一个,而第二个有三个分别是%s%s%c则代表有三个参数。两者结果相同。
对于scanf与printf相类似。
而对一般的函数要如何来做到这一点呢?下面我就来简单介绍一下可变参数列表来实现这一功能。
int average(int n, ...){ va_list arg; //typedef char * va_list; int i = 0; int sum = 0; va_start(arg, n); //#define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) ) for (i = 0; i < n; i++) { sum += va_arg(arg, int); //#define _crt_va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) } return sum / n; va_end(arg); //#define _crt_va_end(ap) ( ap = (va_list)0 )}int main(){ int a = 1; int b = 2; int c = 3; int avg1 = average(2, a, c); int avg2 = average(3, a, b, c); printf("avg1 = %d\n", avg1); printf("avg2 = %d\n", avg2); system("pause"); return 0;}
这段代码是用来求几个数的平均值。main函数中的这两句int avg1 = average(2, a, c);int avg2 = average(3, a, b, c);中的2,3都是为后面函数在栈帧中寻找提供起始地址和控制循环次数。而average函数中:va_list arg;//typedef char * va_list;表示arg是一个char型的指针,arg里面存的是一个地址。va_start(arg, n);//#define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) );这段则表示将arg的地址赋值为位置参数列表中第一个未知参数。在函数栈帧中如图
其中intsizeof()函数的意思是向上取整。
va_arg(arg, int);
//#define _crt_va_arg(ap,t) ( (t )((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) );即((int )((arg+=_INTSIZEOF(int))-_INTSIZEOF(int)))此时arg是一个int型指针,指向第二个未知参数,而表达式取的值是第一个未知参数的值。在函数栈帧中这样表示:
va_end(arg);
//#define _crt_va_end(ap) ( ap = (va_list)0 )
循环结束后给arg赋空指针。
在运用可变参数列表时,需要注意传n和传类型!va_arg这个表达式执行一次后就会指向下一个变量,不再是当前变量,在使用时需谨慎!可变参数列表在使用是只能从第一个挨个取直到最后一个,中间不能跳过几个变量!
阅读全文
0 0
- 浅析可变参数列表
- 浅析可变参数列表
- 可变参数列表浅析
- 浅析可变参数列表
- 浅析可变参数列表的使用
- 浅析可变参数列表及实例分析
- 浅析可变参数
- 浅析可变参数
- 可变参数浅析
- Java可变参数列表
- 可变参数列表
- 关于可变参数列表
- 可变参数列表
- c++ 可变参数列表
- 可变参数列表
- cstdarg可变参数列表
- 可变参数列表
- java可变参数列表
- Centos6.3下rsync+inotify服务器数据同步(备份)
- fiddler扩展模拟弱网络环境设置
- input输入框My97时间插件与值得获取
- logistic regression(二项 logistic 与 多项logistic )
- 3D Graphics with OpenGL Basic Theory
- 浅析可变参数列表
- c++中运算符&,&&,|,||的区别
- 畅谈分布式事物
- Mybatis代码生产工具(MyEclipse10环境下)
- arm汇编进入C函数分析,C函数压栈,出栈,传参,返回值
- [转]Java 单利模式6种实现方式
- Unity 物体根据鼠标移动而转动
- 一枚资深设计师的十年成长漂泊故事
- map,hash_map和unordered_map 实现比较