zoukankan      html  css  js  c++  java
  • va_list原理及用法

    最后更新: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 )
      

    图解
    image_1b9i3i110cb01g4f1p8611vrjmsm.png-11.4kB

  • 相关阅读:
    谷歌将用QUIC传输层技术加速互联网
    无人自助洗车机漏洞
    什么是区块链,为什么它越来越受欢迎
    域名Whois数据和隐私是最大风险
    什么原因?全球许多网络提供商推迟部署IPv6
    FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅱ
    C#中读写INI配置文件
    C#读取和导出EXCEL类库(可操作多个SHEET)
    Javascript刷新页面的几种方法
    用C#抓取AJAX页面的内容
  • 原文地址:https://www.cnblogs.com/gaox97329498/p/12070149.html
Copyright © 2011-2022 走看看