C语言之传递可变参数

C语言之传递可变参数

文章链接:

知识点

  1. 传递int可变参数个数;
  2. 传递char类型可变参数个数;
  3. 传递logn类型可变参数个数;
  4. 传递可变参数个数特例;
  5. 新名词记录{stdarg.h, va_list, va _start(), va _arg(), va _end()}

概述

在一个状态下,我们可能我们需要传递的参数的个数是可变的。C 语言为这种情况提供了一个解决方案,它允许您定义一个函数,能根据具体的需求接受可变数量的参数。可以是编程更加的灵活,适应各种业务要求。

定义

可变参数的定义如下:

ruturnType funcName(classType, ... ){}

这个和一般的函数并没有什么两样,只是在第二个参数后,利用“…”代替后面跟着不定个参数。

当我们需要获取传入来的可变参数,就需要用到stdarg.h函数库里面的几个方法,他们分别是:

1、类型:va_list,用来接受"..."代表的全部参数。
2、va_start(va_list, type):初始化va_list声明的变量。type可以是int,也可以是char等类型。
3、va_arg(va_list, returnType):参数1是va_list生命的变量,参数2是从参数1中获取到的类型,即是"..."传入的类型。并且是指针指向va_list的下一个数据。
4、va_end(va_list):清空va_list变量,使得指针不可用,和va_start配对使用。

使用

可能上面说了这么多,你都没懂,下面我们直接来看看如何使用,方便理解。

1. 传入int类型数据:首先来看我们传入n个int数据,然后计算出平均值返回回来。

/**
 * 求任意个数量的平均数
 * 
 * @param num
 * @param ... 入参必须为int类型
 * @return 
 */
double averge(int num, ...) {
    va_list valist;
    double sum;
    va_start(valist, num);
    for (int i = 0; i < num; i++) {
        sum = sum + va_arg(valist, int);//参数2说明返回的类型为int
    }
    va_end(valist);
    return sum / num;
}

//调用函数
printf("averge: %d\n", averge(3, 5, 15, 10));
//结果:averge: 10

可以看到上面的参数,我们首先定义一个va_ list类型的变量,然后使用va_ start方法初始化valist,然后就可以利用va_ arg方法一次取出传入可变参的每一个值了。在最后我们必须调用va_end释放valist占用的空间。

2. 传入char类型数据:
然后我们传入char类型的数据。
如下代码所示:

/**
 * 不定个参数为char类型
 * 
 * @param num
 * @param ... 入参必须为char类型参数
 */
void charTest(int num, ...) {
    va_list valist;
    char ch[num];
    char *pot = ch;
    va_start(valist, num);
    for (int i = 0; i < num; i++) {
        strcat(ch, va_arg(valist, char*));
    }
    printf("ch : %s\n", ch);
}

如何来取得char类型的数据呢?这里我们要返回的数据是char*指针类型的。然后使用strcat方法将字符串拼接取来。

charTest(3, "a", "b", "c");
//结果:ch : abc

3. 传入long类型数据:
long类型数据也是和int类型数据是一样的操作的。

/**
 * 传入long类型数据的不定个参数
 * 
 * @param num
 * @param ...
 */
void longTest(int num, ...){
    va_list valist, valist2;
    va_start(valist2, num);//初始化valist2
    va_copy(valist, valist2);//将valist2复制给valist,初始化为valist2
    for(int i = 0; i < num; i++){
        long l = va_arg(valist, long);
        printf("logn %d is %ld\n", i, l);
    }
}

//调用
longTest(4, 2323423, 2989784, 2797875, 29898986);
    /**logn 0 is 2323423
logn 1 is 2989784
logn 2 is 2797875
logn 3 is 29898986
*/

在上面,说一下va_copy(dest, src)函数,此函数是将dest初始化为src数据。两个参数都是va _list类型的变量。

4. 第一个参数不一定都要int类型:

/**
 * 参数传递char+不定个数
 * @param msg
 * @param ...
 */
void funcTest(char msg, ...) {
    va_list argp;
    int argno = 0;
    char para;
    va_start(argp, msg);
    while(1){
        char *p;
        p = va_arg(argp, char *);
        if(strcmp(p, "") == 0) break;//判断跳出的条件,否则会进入死循环
        printf("Parameter #%d is : %s\n", argno, p);
        argno++;
    }
    va_end(argp);
}

如上面所示,第一个参数我们并没有写成int类型,而是一个char类型,剩下的操作就和之前的是一样的。然后,调用测试此函数。

    funcTest('hi', "i", "am", "yao", "jingtang!", "");
    /**
     * Parameter #0 is : i
Parameter #1 is : am
Parameter #2 is : yao
Parameter #3 is : jingtang!
     */

可以看到依然可以取出所有的入参。

总结

上面讲解了在C语言中传递可变参数的实例,主要有传递int,long,char以及最后一个比价特殊的示例。我们只要理解va_list, va _start(), va _arg(), va _end()几个函数就差不多了。

以上就是所有内容,如有任何问题,请及时与我联系,谢谢。

你可能感兴趣的:(C语言)