printf中va_list的实现

首先声明下面这个va_list的实现,只适用于32位的机器,像单片机这样int 是2Byte的不适合,但是原理是一样的。

点击(此处)折叠或打开

  1. typedef char * va_list;
  2. #define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )
  3. #define va_start(ap,v) ( ap = (va_list)&+ _INTSIZEOF(v) )
  4. #define va_arg(ap,t) ( *(*)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
  5. #define va_end(ap) ( ap = (va_list))

  6. void test_vparameter(int i,...)
  7. {
  8.     int mm;
  9.     va_list argv;
  10.     va_start(argv,i);
  11.     while(i--)
  12.     {
  13.         mm=va_arg(argv,int);
  14.         putc(mm);
  15.     }
  16.     va_end(argv);
  17. }
1. va_list
   在调用va_start之前参数都己压入栈中,因为其它的都是可变参数,只有fmt是确定的,fmt是最后压入栈中的,并且每个参数在栈中占用的空间是一样的,所以可以由第一个参数fmt依次推算出其它参数的地址。
2. va_start
   a. (va_list)&t 取第一个参数fmt的地址
   b. (va_list)&t+_INT_SIZEOF(t) 第一个参数的地址加上参数的长度,此时ap指向了第二个参数即ap指向了第一个可变的参数。

3. va_arg
   a. ap+=__INT_SIZEOF(t)
ap移动指向第二个可变参数
   b. (ap+=__INT_SIZEOF(t))-__INT_SIZEOF(t)
用指针运算,确定第一个可变参数的地址
   c. (t*)((ap+=__INT_SIZEOF(t))-__INT_SIZEOF(t))
进行强制类型转化
   d. (*(t*)((ap+=__INT_SIZEOF(t))-__INT_SIZEOF(t)))
取出第一个可变参数地址中的值
转自http://blog.chinaunix.net/uid-26009923-id-3261696.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值