0
点赞
收藏
分享

微信扫一扫

C语言可变参数函数的主要应用与特性分析


Tags: C/C++ Syntax Varadic_Args

写在前面

最近在看的一份关于​​2048​​​游戏的​​OpenGL​​​实现的​​C​​​语言源代码, 其中用到了一个比较独特的语法, 叫做可变参数, 乍一看还以为是​​C++11​​​中引入的可变参数模板, 实际上却是​​C​​​语言独有的特性, 下面来分析一下这个语法特性, 并用来实现一些小例子, 以及C和C++的这类型语法的一些对比. 参考了​​Wikipedia​​​, ​​cppreference.com​​和其他一些博客文章.

下面是一些需要的头文件, 这里采用了C++写, 如果用C的话改成​​stdarg.h​​之类即可

#include <cstdarg> // you need to include this to use variable numbers of args
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <climits>//INT_MAX

输出

void printArgs(int arg1, ...) {
/* 打印函数的所有参数, 直到出现负数 */
va_list ap;
va_start(ap, arg1); // 捕获初始值
// va_arg指定捕获参数的类型, 返回下一个参数
for (int i = arg1; i > 0; i = va_arg(ap, int))
printf("%d ", i);
va_end(ap); //释放参数列表内存
putchar('\n'); //以换行符结尾
}

平均值

这里我用两种方法, 分别是设置跳出条件(可以有任意数量的参数, 但是必须选用一个特定值作为跳出条件)和固定输入的数量(不能有任意数量参数, 但是不需要判断特殊值进行循环的跳出)

void calAverage(int arg1, ...) {
/*这个函数需要给定循环跳出的条件, 这里我设置为INT_MAX */
va_list ap;
int i, total = 0, j = 0;

va_start(ap, arg1);
for (i = arg1; i != INT_MAX; i = va_arg(ap, int)) {
total += i;
j++;
}
va_end(ap);
printf("total(%d) is: %d, average is: %.2f\n", j, total,
(double) total / j);
}

void calAverage1(int num, ...) {
/*这里指定了读取参数的数量, 放在第一个参数位置*/
va_list ap;
int i, total = 0;

va_start(ap, num);
for (i = 0; i < num; i++) {
total += va_arg(ap, int);
}
va_end(ap);
printf("total(%d) is: %d, average is: %.2f\n", num, total,
(double) total / num);
}

最值

void findMax(int arg1, ...) {
/*这个函数需要给定循环跳出的条件, 这里我设置为INT_MAX */
va_list ap;
int i, max1=0;

va_start(ap, arg1);
for (i = arg1; i != INT_MAX; i = va_arg(ap, int)) {
max1=max1<i?i:max1;
}
va_end(ap);
printf("Max value is: %d\n\n", max1);
}

完整测试代码

​​C-Cpp_Proj/c-varadic-args.cpp at main · Apocaly-pse/C-Cpp_Proj (github.com)​​.

结果:

printArgs test:
84 51
findMax test:
Max value is: 84

calAverage test:
total(6) is: 202, average is: 33.67
total(6) is: 202, average is: 33.67
calAverage time compare:
test1, CLOCKS_PER_SEC is: 1000000, total time is: 216.106000ms

test2, CLOCKS_PER_SEC is: 1000000, total time is: 213.071000ms

可见指定数量之后速度要略快一些.


举报

相关推荐

0 条评论