如何自定义可变参数函数

在我们编写代码中,有时需要我们自定义可变参数函数,像库函数中有pirntf,ioctl都是可变参数函数,如果我们要实现自定义可变参数,一般要实现像int ioctl(int fd, unsigned long request, ...)这种功能的。下面讲解如何实现ioctl这个类型函数

1.通过分析printf函数:

1)typedef char *va_list;

 

2)#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) //计算n占用大小

 

3)#define va_start(ap,v)( ap = (va_list)&v + _INTSIZEOF(v) ) //获取第一个可变参数在栈地址(在栈中参数入参顺序为从右至左,栈底为高地址,栈顶为底地址,&v+_INTSIZEOF(v) ,这里&v是最后一个固定参数的起始地址,再加上其实际占用大小后,就得到了第一个可变参数的起始内存地址。所以我们运行va_start (ap, v)以后,ap指向第一个可变参数在的内存地址

 

4)#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )

/*这个宏做了两个事情,

①用用户输入的类型名对参数地址进行强制类型转换,得到用户所需要的值

②计算出本参数的实际大小,将指针调到本参数的结尾,也就是下一个参数的首地址,以便后续处理。*/

 

5)#define va_end(ap) ( ap = (va_list)0 ) 

2.模板:

 

void myioctl(int select,...)

{

va_list args;

va_start(args, select);//将args赋值为第一个可变参数地址

switch(select){

case 1:

//假设这个选项需要两个可变参

int i=va_arg(args,int);

char c=va_args(args,char);

......

va_end(args);

case 2:

.....

}

va_end(args);

}

3.举例子

#include<stdio.h>
#include<stdarg.h>//第一部分说明的那几个宏就在这个头文件实现的

#if 0
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
typedef char *va_list1;
#define va_start1(ap,v)( ap = (va_list1)&v + _INTSIZEOF(v) ) 
#define va_arg1(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end1(ap) ( ap = (va_list1)0 ) 

#endif
void myioctl(int select,...)
{
va_list args;
int i;
int c;
char* d;
va_start(args, select);
switch(select){
case 1:
i=va_arg(args,int);
c=va_arg(args,int);
printf("test:i=%d,c=%d\n",i,c);
break;
case 2:
i=va_arg(args,int);
d=va_arg(args,char*);
printf("test:i=%d,c=%s\n",i,d);
break;
}
va_end(args);
return;
}
int main()
{
int a=0x34,b=0x23;
char* string="haode";
myioctl(0x1,a,b);
myioctl(0x2,a,string);
return 0;
}

疑问:很奇怪,我不用库里自带的va_start,va_args(即不用头文件stdarg.h),而是自定义上面的,居然不行,不知道怎么回事。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值