Intro
有一天看C代码看到某个方法有这样的定义:在函数形参列表处,有...
的写法,就像Java中的不定参数那样。
如:
int printf(const char * __restrict, ...) __printflike(1, 2);
int scanf(const char * __restrict, ...) __scanflike(1, 2);
那么C语言中的不定参数特性,是怎样使用的呢,以及我们如何利用该特性,封装自己的函数?
语法测试
依赖库
需要用到 stdarg.h
中的三个函数:
#define va_start(ap, param) __builtin_va_start(ap, param)
#define va_end(ap) __builtin_va_end(ap)
#define va_arg(ap, type) __builtin_va_arg(ap, type)
新函数使用测试:遍历并打印不定参数中的值
主要是测试一下上面提到的三个库函数的使用。
#include <stdio.h>
#include <stdarg.h>
// 声明列表的结束值
#define ARGUMENTS_END_VALUE -1
void printMultiArgs(int firstArgs, ...) {
// 声明参数列表的变量
va_list ap;
// 初始化参数列表
va_start(ap, firstArgs);
printf("%d\n", firstArgs);
int currValue;
while ((currValue = va_arg(ap, int)) != ARGUMENTS_END_VALUE) {
printf("%d\n", currValue);
}
// 结束参数列表
va_end(ap);
}
int main(int argc, const char * argv[]) {
printMultiArgs(1,2,3,4,5,6,7,8,9, ARGUMENTS_END_VALUE);
return 0;
}
用两种方式封装函数:对多个int值求和
//
// main.c
// C不定参数
//
// Created by wuyujin1997 on 2023/1/23.
//
//#define va_start(ap, param) __builtin_va_start(ap, param)
//#define va_end(ap) __builtin_va_end(ap)
//#define va_arg(ap, type) __builtin_va_arg(ap, type)
#include <stdio.h>
#include <stdarg.h>
// 声明列表的结束值
#define ARGUMENTS_END_VALUE -1
void printMultiArgs(int firstArgs, ...) {
// 声明参数列表的变量
va_list ap;
// 初始化参数列表
va_start(ap, firstArgs);
printf("%d\n", firstArgs);
int currValue;
while ((currValue = va_arg(ap, int)) != ARGUMENTS_END_VALUE) {
printf("%d\n", currValue);
}
// 结束参数列表
va_end(ap);
}
/// 对多个int变量求和(需要提前约定好参数结束的标志值 ARGUMENTS_END_VALUE)
/// - Parameter firstArgs: <#firstArgs description#>
int sum1(int firstArgs, ...) {
int result = 0;
va_list ap;
va_start(ap, firstArgs);
result+= firstArgs; // 手动处理第一个参数
int currValue;
while ((currValue = va_arg(ap, int)) != ARGUMENTS_END_VALUE) {
result += currValue;
}
va_end(ap);
return result;
}
/// 对多个int变量求和(需要主动本方法:不定参数的个数是多少)
/// - Parameters:
/// - count: 不定参数的个数
/// - firstArgs: 第一个参数,显式的形参
int sum2(int count, int firstArgs, ...) {
int result = 0;
va_list ap;
va_start(ap, firstArgs);
result += firstArgs;
for (int i = 1; i < count; i++) {
int currValue = va_arg(ap, int);
// printf("%d %d\n", i, currValue);
result += currValue;
}
va_end(ap);
return result;
}
int main(int argc, const char * argv[]) {
printMultiArgs(1,2,3,4,5,6,7,8,9, ARGUMENTS_END_VALUE);
printf("sum1 %d\n", sum1(1,2,3,4,5,6,7,8,9, ARGUMENTS_END_VALUE));
int LENGTH = 9;
printf("sum2 %d\n", sum2(LENGTH, 1,2,3,4,5,6,7,8,9, ARGUMENTS_END_VALUE));
return 0;
}
执行结果:
总结
- 需要引入头文件 #include <stdarg.h>
- 一个新类型,三个新函数
- 类型 va_list
- 函数,其中 ap 为 va_list 类型的变量。
- va_start(ap, param) param为不定参数列表的第一个参数。
- va_arg(ap, type) 不定参数中变量的类型吗,如int, short, long 等。
- va_end(ap)
- 如何确定 va_arg 的size/有多少个元素? 没有原生的属性/变量可以告诉我们。
- 约定一个值作为 end_value ,而且要保证:这个值不会出现在传入的多个参数值中。
- 在咱自己封装的函数中,新增一个参数用于告知被调函数内部:本次不定参数的size是多少。
- 注意不定参数的类型匹配。
总结
到此这篇关于C语言中不定参数 ... 的语法以及函数封装的文章就介绍到这了,更多相关C语言不定参数 ...内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!