最后更新:2017-02-22

这是一篇很早很早的博客文章,虽然很基础,但是毕竟曾经历程,因此也保存下来

1. 概念

va_list 是在C语言中定义的宏,指在解决

  • 变参问题是指参数的个数不定,可以是传入一个参数也可以是多个;
  • 可变参数中的每个参数的类型可以不同,也可以相同;
  • 可变参数的每个参数并没有实际的名称与之相对应。

2. va_list的用法

  1. 首先在函数里定义一具va_list型的变量,这个变量是指向参数的指针;

  2. 然后用va_start宏初始化变量刚定义的va_list变量;

  3. 然后用va_arg返回可变的参数,va_arg的第二个参数是你要返回的参数的类型(如果函数有多个可变参数的,依次调用va_arg获取各个参数);

  4. 最后用va_end宏结束可变参数的获取。

    例如

    - (NSArray *)combine:(NSString *)string, ...
    { NSMutableArray *arrayM = [NSMutableArray array]; [arrayM addObject:string]; va_list list;
    id tag; va_start(list, string); while ((tag = va_arg(list, id))) {
    [arrayM addObject:tag];
    } va_end(list);
    return [arrayM copy];
    }

3. 原理解释

  1. 变量

    #ifdef _M_ALPHA
    typedef struct {
    char *a0; /* pointer to first homed integer argument */
    int offset; /* byte offset of next parameter */
    } va_list;
    #else
    typedef char * va_list;
    #endif _M_ALPHA是指DEC ALPHA(Alpha AXP)架构。所以一般情况下va_list所定义变量为字符指针。
  2. _INTSIZEOF 宏,获取类型占用的空间长度,最小占用长度为int的整数倍:

    #define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
  3. va_start,获取可变参数列表的第一个参数的地址(ap是类型为va_list的指针,v是可变参数最左边的参数)

    #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
  4. va_arg宏,获取可变参数的当前参数,返回指定类型并将指针指向下一参数(t参数描述了当前参数的类型):

    #define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
  5. va_end宏,清空va_list可变参数列表:

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

图解

最新文章

  1. jQuery从无知到无所不知
  2. MySQL for Visual Studio Version
  3. android 实现自定义卫星菜单
  4. C#的面向对象特性之封装
  5. js 事件监听封装
  6. Vmware虚拟机下三种网络模式配置
  7. SignalR在ASP.NET MVC中的应用
  8. nginx服务器的作用与简单搭建(windows)
  9. PAT1136:A Delayed Palindrome
  10. align-content 与 align-items 区别
  11. 20165221 《网络对抗技术》EXP1 PC平台逆向破解
  12. css的小知识
  13. postgresql分区(引用)
  14. MPI-Hydra Process Managerment Framework
  15. [HEOI2016/TJOI2016]序列
  16. [PyImageSearch] Ubuntu16.04 使用OpenCV和python识别信用卡 OCR
  17. BBS--首页、个人站点、ORM
  18. 【372】Kaggle 相关经验
  19. MATLAB总结二
  20. 自学iOS-获取当前时间

热门文章

  1. ssh远程登录过程中卡住
  2. MySQL-快速入门(2)数据类型
  3. Charles的app抓包配置和抓包节点为unknown、乱码、手机无法上网等问题的处理
  4. W同学的新画板 QDUOJ 线段树 区间颜色段数
  5. nodejs版实现properties后缀文件解析
  6. letsencrypt 免费SSL证书申请, 自动更新
  7. 剑指offer-复杂链表的复制-链表-python
  8. 01-Django-urls
  9. Java httpClint实现文件上传
  10. 长沙理工大学第十二届ACM大赛-重现赛 D 小M和天平 (01背包)