• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

c函数中传递可变参数:va_list,va_start,va_arg,va_end

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

可变参数函数就是输入的参数个数是可变的

最经典的是printf和scanf,这两个函数的声明如下:

1 int printf(const char *format, ...);
2 int scanf(const char *format, ...);

这两个函数声明中省略号(...)表示任意个数的参数

函数的数据是存放于栈中的,那么给一个函数传递传递参数的过程就是将函数的参数从右向左逐次压栈,例如:

func(int i, char c, doube d)

这个函数传递参数的过程就是将d,c,i逐次压到函数的栈中,由于栈是从高地址向低地址扩展的,所以d的地址最高,i的地址最低。

典型的写法如下:

1 void func(char *fmt, ...){
2       va_list ap;
3       va_start(ap, fmt);
4       va_arg(ap, int);
5       va_end(va);      
6 }

  这里ap是一个指针,指向参数的地址。

  va_start()让ap指向函数的最后一个确定的参数(声明程序中是fmt)的地址。

  va_arg()根据ap指向的地址和第二个参数所确定的类型,将这个参数的中的数据提取出来,作为返回值,同时让ap指向下一个参数。

  va_end()让ap这个指针指向0。

 

关于这三个参数实现的宏可以参看下面的实现:

 

1 #define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )
2 #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) //第一个可选参数地址
3 #define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) //下一个参数的值
4 #define va_end(ap) ( ap = (va_list)0 ) // 将指针置为无效

 

 

以下为编译PL0语言的SET.c源码中的createset()函数,在此函数中就是用了可变长参数:

 1 void setinsert(symset s, int elem)
 2 {
 3     snode* p = s;
 4     snode* q;
 5 
 6     while (p->next && p->next->elem < elem)
 7     {
 8         p = p->next;
 9     }
10     
11     q = (snode*) malloc(sizeof(snode));
12     q->elem = elem;
13     q->next = p->next;
14     p->next = q;
15 } // setinsert
16 
17 symset createset(int elem, .../* SYM_NULL */)
18 {
19     va_list list;
20     symset s;
21 
22     s = (snode*) malloc(sizeof(snode));
23     s->next = NULL;
24 
25     va_start(list, elem);
26     while (elem)
27     {
28         setinsert(s, elem);
29         elem = va_arg(list, int);
30     }
31     va_end(list);
32     return s;
33 } // createset

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C#三种模拟自动登录和提交POST信息的实现方法发布时间:2022-07-13
下一篇:
链式栈-C语言实现发布时间:2022-07-13
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap