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

图解

va_list原理及用法的更多相关文章

  1. Nmap扫描原理与用法

    Nmap扫描原理与用法 1     Nmap介绍 Nmap扫描原理与用法PDF:下载地址 Nmap是一款开源免费的网络发现(Network Discovery)和安全审计(Security Audit ...

  2. PHP依赖注入原理与用法分析

    https://www.jb51.net/article/146025.htm 本文实例讲述了PHP依赖注入原理与用法.分享给大家供大家参考,具体如下: 引言 依然是来自到喜啦的一道面试题,你知道什么 ...

  3. JSON Web Token(JWT)原理和用法介绍

    JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案.今天给大家介绍一下JWT的原理和用法. 官网地址:https://jwt.io/ 一.跨域身份验证 Internet服务无法与 ...

  4. Java并发-volatile的原理及用法

    Java并发-volatile的原理及用法 volatile属性:可见性.保证有序性.不保证原子性.一.volatile可见性 在Java的内存中所有的变量都存在主内存中,每个线程有单独CPU缓存内存 ...

  5. NSPredicate用法总结(Cocoa框架中的NSPredicate用于查询,原理和用法都类似于SQL中的where,作用相当于数据库的过滤取)

    简述:Cocoa框架中的NSPredicate用于查询,原理和用法都类似于SQL中的where,作用相当于数据库的过滤取. 定义(最常用到的方法): NSPredicate *ca = [NSPred ...

  6. Web安全学习笔记之Nmap扫描原理与用法

    1     Nmap介绍 Nmap扫描原理与用法PDF:下载地址 Nmap是一款开源免费的网络发现(Network Discovery)和安全审计(Security Auditing)工具.软件名字N ...

  7. 初涉IPC,了解AIDL的工作原理及用法

    初涉IPC,了解AIDL的工作原理及用法 今天来讲讲AIDL.这个神奇的AIDL,也是近期在学习的,看了某课大神的解说写下的blog,希望结合自己的看法给各位同价通俗易懂的解说 官方文档:http:/ ...

  8. 41、扩展原理-ApplicationListener用法

    41.扩展原理-ApplicationListener用法 ApplicationListener 监听容器中发布的事件.事件驱动模型开发: public interface ApplicationL ...

  9. Python实现的选择排序算法原理与用法实例分析

    Python实现的选择排序算法原理与用法实例分析 这篇文章主要介绍了Python实现的选择排序算法,简单描述了选择排序的原理,并结合实例形式分析了Python实现与应用选择排序的具体操作技巧,需要的朋 ...

随机推荐

  1. numpy库的认识以及数组的创建

    numpy库 numpy是Python数值计算最重要的基础包.大多数提供科学计算的包都是用NumPy的数组作为构建基础.numpy十分高效,基于NumPy的算法要比纯Python快10到100倍(甚至 ...

  2. P1219八皇后

    这个题是一道USACO的经典dfs,与我见面的时间起码七个月了. 放置n个皇后于n*n棋盘,他们不能互相吃(行,列,对角线),问有几种摆法?于是想到了dfs(自我认为有图的就不用DP).首先确定好了要 ...

  3. 思维体操: HDU1008 Elevator

    Elevator Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  4. java代码转化为jar包,再转化为.exe文件步骤

    下面是具体步骤: 一.先把自己的程序发布成jar文件 这是eclipse自带的功能,右键工程包-->Export 然后选择Java-->JAR file,next 选择输出路径,next ...

  5. 【学习总结】快速上手Linux玩转典型应用-目录

    内容链接 慕课网:快速上手Linux玩转典型应用 目录 第1章-课程介绍 第2章-linux简介 第3章-CentOS的安装 第4章-准备工作 第5章-远程连接SSH专题 第6章-linux常用命令讲 ...

  6. Aniamtion加载动画

    css新增样式Animation的运用 希望可以通过这个案例加深对Animation以及Transform 两大api的认识 效果图如下: 在这里需要注意的是:理应通过发送服务器请求来获取图片,从而达 ...

  7. Python 操作sqlite数据库及保存查询numpy类型数据(一)

    # -*- coding: utf-8 -*- ''' Created on 2019年3月6日 @author: Administrator ''' import sqlite3 import nu ...

  8. 33. Search in Rotated Sorted Array (JAVA)

    Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...

  9. 如何学习ios(摘自知乎https://www.zhihu.com/question/20016551)

    著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:Wang Hailong链接:https://www.zhihu.com/question/20016551/answer/1 ...

  10. wamp2.5最简单的虚拟主机配置

    1.配置host文件 2.配置httpd.conf 去掉# LoadModule rewrite_module modules/mod_rewrite.so Include conf/extra/ht ...