可变函数定义及使用
来源:互联网 发布:手机用户mac绑定错误 编辑:程序博客网 时间:2024/06/01 19:00
关键词:
stdarg.h头文件
va_list
va_start
va_arg
va_end
1.定义可变参数函数
#include<stdarg.h>
返回类型 函数名(参数类型1 参数1, 参数类型2 参数2, ...)
例如:
int func(int i, ...)
int func(int i, int j, int k, ...)
2.获取参数
va_list parg //定义parg指针
va_start(parg, i) //初始化parg指针,执行后parg->j
va_arg(parg, int) //获取参数,这里参数类型可以为别的float等等可以与i类型不同,pargs会按此类型存储的长度取数据,并移位,因为执行va_start(parg, i) 后parg->j,则执行//va_arg(parg, int) ,parg按整形int取4个字节
3.清理
va_end(parg) //可变函数返回前调用
实列:
addnum(1,2,3,4,0) //实现1:求和1+2+3+4 0表示结束取值(当然可以为其它特殊数-1等等),循环加的时候遇到0表示参数结束(加结束)
addnum(4,1,2,3,4)//实现2:有4个数1,2,3,4求和
sum_series(4, 0.5, 0.25, 0.125, 0.06254)//有4个小数0.5, 0.25, 0.125, 0.06254求这4个数的和
代码1:
#include<stdio.h>#include<stdarg.h>int addnum(int i, ...) {va_list parg;va_start(parg, i);//i=1,&1=0xbff66ac0,执行va_start后parg=0xbff66ac4printf("&i = %p, parg = %p\n", &i, parg); //打印地址:&i = 0xbff66ac0, parg=0xbff66ac4 数据2地址int num =i ;int v = va_arg(parg, int);//开始parg=0xbff66ac4,从0xbff66ac4处取4个字节数据给v,即v=2,此后parg=0xbff66ac8printf("parg = %p\n,", parg); //打印地址:parg=0xbff66ac8 数据3地址while( v !=0) //取到的数据为0后不往下取数据{num = num + v;v = va_arg(parg, int);//依次取3 4 0printf("parg = %p\n", parg);//依次打印4,0,*,地址:parg=0xbff66acc 数据4地址//parg=0xbff66ad0 数据0地址//parg=0xbff66ad4,}va_end(parg);return num;}int main(){printf("%d\n", addnum(1,2,3,4,0));//1,2,3,4,0在栈中,&1=0xbff66ac0,&2=0xbff66ac4,&3=0xbff66ac8,&4=0xbff66acc,&0=0xbff66ad0return 0;}
cc addnum.c
./a.out
&i = 0xbff66ac0, parg = 0xbff66ac4parg = 0xbff66ac8,parg = 0xbff66accparg = 0xbff66ad0parg = 0xbff66ad410
由运行结果可知:
高地址:最后一个参数
。。。。
低地址:第一参数
具体可参考:
点击打开链接中参数在栈中的分布
若想了解更具体可以参考此blog地址:
http://blog.csdn.net/chchchdx123/article/details/7597149
或下面链接:
点击打开链接
代码2:
基于代码1改进:
#include<stdio.h>#include<stdarg.h>int addnum(int i, ...) {va_list parg;va_start(parg, i);printf("&i = %p, parg = %p, *parg = %d\n", &i, parg, *parg);int num=0, v;#if 0int num =i ;int v = va_arg(parg, int);printf("parg = %p\n,", parg);while( v !=0){num = num + v;v = va_arg(parg, int);printf("parg = %p\n", parg);}#endiffor(; i; i--){printf("parg = %p, *parg = %d\n", parg, *parg);v = va_arg(parg, int);num +=v;}va_end(parg);return num;}int main(){//printf("%d\n", addnum(1,2,3,4,0));printf("%d\n", addnum(4,1,2,3,4));return 0;}
结果:
root@book-desktop:/work/video_example# cc addnum.c
root@book-desktop:/work/video_example# ./a.out
&i = 0xbfd09e50, parg = 0xbfd09e54, *parg = 1
parg = 0xbfd09e54, *parg = 1
parg = 0xbfd09e58, *parg = 2
parg = 0xbfd09e5c, *parg = 3
parg = 0xbfd09e60, *parg = 4
10
对比代码1和代码2可知代码2简洁,易理解
代码3:
#include<stdio.h>#include<stdarg.h>double sum_series(int num, ...){double sum=0.0, t;va_list argptr;va_start(argptr, num);for( ; num; num--){printf("argptr = %p, *argptr = %10.9f\n", argptr, *argptr);t = va_arg(argptr, double);sum +=t;}va_end(argptr);return sum;}int main(){double d;d = sum_series(4, 0.5, 0.25, 0.125, 0.06254);printf("sum of series is %f\n", d);return 0;}
root@book-desktop:/work/video_example# cc doublesum.c doublesum.c: In function ‘sum_series’:doublesum.c:11: warning: format ‘%10.9f’ expects type ‘double’, but argument 3 has type ‘int’root@book-desktop:/work/video_example# ./a.out argptr = 0xbfa0ef64, *argptr = 0.000000000argptr = 0xbfa0ef6c, *argptr = 0.000000000argptr = 0xbfa0ef74, *argptr = 0.000000000argptr = 0xbfa0ef7c, *argptr = 0.000000000sum of series is 0.937540
有一处警告,且输出打印不对
printf("argptr = %p, *argptr = %10.9f\n", argptr, *((double*)argptr));这样就对了
- 可变函数定义及使用
- 可变参函数的定义和使用
- 可变参函数的定义和使用
- 可变参函数的定义和使用
- 可变参函数的定义和使用
- linux下可变参数及宏定义封装函数
- Python定义函数中的可变参数**kw及*args
- C/C++]可变参函数的定义和使用【转】
- 参数可变的函数定义
- 可变参数函数定义要点
- Matlab 定义函数,函数参数个数可变
- 可变长度函数参数的原理及使用
- 可变参数函数的基本原理及使用实现
- 可变参数函数使用
- 使用可变函数
- 带...参数的函数定义及使用
- 函数是什么及怎么定义、怎么使用
- oracle 函数、包的定义及使用
- centos6.2+nginx-1.2.3+php-5.3.17安装脚本
- leetcode之Sqrt(x)
- AppCrashView
- tomcat管理账户配置
- 今生只爱整数
- 可变函数定义及使用
- 广告常用概念小结
- java通过c调用python
- Ubuntu Linux下安装Oracle JDK
- 有关UITableView的contentSize、contentInset和contentOffset
- ios中的变量和属性
- document.all
- VC 保存数据
- Raw-OS源码分析之事件标志