变长参数的讨论

前言

一直以来对变长参数都比较好奇,索性花时间解解痒.

先从数组指针来看

void test1(int* arr,int count)
{
    int sum = 0;
    for (int *p = arr; p < arr + count; p++)
    {
        sum = sum+ *p;
    } 
    printf("%d\n",sum );
}

代码较为简单,此处不再展开.

接下来是可变参数

可变参数需要使用 <stdarg.h> 头文件,请提前导入

  1. 什么是可变参数?
    • 可变参数是函数或方法中形如int show(int a,...)这样的的参数
  2. 可变参数的相关规定
    • ... 不能单独出现,且只能放在参数列表中的最后
    • 变长参数的类型没有限定,使用时最好统一类型,避免类型安全问题
    • 变长参数的个数没有限定,调用时一般以0x00NULL/nil结尾

-

void test2(int a,...)
{
    int sum = a;
    //声明变长参数列表vl
    va_list vl;
    //va_start :将变长参数的前一个参数的地址存入vl
    va_start(vl,a);
    int next;
    //va_arg   :将vl向后偏移sizeof(int),并返回偏移后长度为sizeof(int)的数据
    //判断 next 是否为 0x00 ,如果不为 0x00 则继续遍历
    while( (next = va_arg(vl,int)) )
    {
        sum+= next;
    }
    //释放变长参数列表vl
    va_end(vl);
    printf("%d\n",sum );
}

调用形式

int main(int argc,char * args[])
{    
    int arr[] = {1,2,3,4,5};
    //数组指针
    test1(arr,5);
    printf("---------\n");
    //变长参数
    test2(1,2,3,4,5,6,NULL);
    return 0;
}

输出结果

15
---------
21

小结

... 的类型不做限定,因此在函数或方法调用时可传递任何类型,包括但不限于ObjC中使用的id等类型

另外暂未查看到<stdarg.h>的源码,只能推测其中也是使用的数组指针进行的处理.如有纰漏请批评指正.