在一个状态下,我们可能我们需要传递的参数的个数是可变的。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()几个函数就差不多了。
以上就是所有内容,如有任何问题,请及时与我联系,谢谢。