C语言中不定参数 ... 的语法、函数封装
创始人
2024-05-16 01:44:11
0

文章目录

    • Intro
    • 语法测试
      • 依赖库
      • 新函数使用测试:遍历并打印不定参数中的值
      • 用两种方式封装函数:对多个int值求和
    • 总结

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 
#include // 声明列表的结束值
#define ARGUMENTS_END_VALUE -1void 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 
#include // 声明列表的结束值
#define ARGUMENTS_END_VALUE -1void 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
  • 一个新类型,三个新函数
    • 类型 va_list
    • 函数,其中 apva_list 类型的变量。
      • va_start(ap, param) param为不定参数列表的第一个参数。
      • va_arg(ap, type) 不定参数中变量的类型吗,如int, short, long 等。
      • va_end(ap)
  • 如何确定 va_arg 的size/有多少个元素? 没有原生的属性/变量可以告诉我们。
    • 约定一个值作为 end_value ,而且要保证:这个值不会出现在传入的多个参数值中。
    • 在咱自己封装的函数中,新增一个参数用于告知被调函数内部:本次不定参数的size是多少。
  • 注意不定参数的类型匹配。

相关内容

热门资讯

菏泽考区2025年国家统一法律... 大众网记者 王奉国 菏泽报道 10月12日,菏泽考区2025年国家统一法律职业资格主观题考试结束。考...
电费优惠进商户 政策红利暖人心... 电费成本是商铺经营的重要支出之一。为切实减轻商户负担,优化营商环境,古槐街道东门社区网格中心走进辖区...
苹果再陷 AI 版权纠纷:神经... IT之家 10 月 13 日消息,在被指控使用盗版书籍训练其人工智能系统约一个月后,苹果公司再次面临...
深圳市区现剧毒银环蛇!目击者:... 近日,有市民发布视频称,自己在翠竹公园散步,疑似遇到剧毒银环蛇。 目击者对第一现场记者称,当晚他在翠...
不再参加各种讲座是律师“进化”... 最近见了一位有一面之缘的微信好友,添加好几年了,没怎么见他发朋友圈,感觉都快消失了,突然约我在律所附...
美国俄亥俄州议员拟立法阻止AI... IT之家 10 月 13 日消息,据外媒 Futurism 12 日报道,美国俄亥俄州利金县众议员 ...
Windows 10将于10月... 综合《新西兰先驱报》等媒体12日报道,美国微软公司将于10月14日起,停止对Windows 10系统...
化工行业有望受益于”反内卷“政... 化工行业过去产能过剩问题较为突出,“反内卷”势在必行。9月26日,《石化化工行业稳增长工作方案(20...