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是多少。
  • 注意不定参数的类型匹配。

相关内容

热门资讯

口碑好的拆迁律师机构推荐,为您... 在拆迁过程中,许多人会遭遇各种复杂的法律问题,因此选择一家靠谱、诚信且口碑好的拆迁律师机构至关重要。...
菏泽市司法局召开全市法律援助工... 为深入贯彻落实《中华人民共和国法律援助法》,全面提升全市法律援助工作水平,12月16日,菏泽市司法局...
潮起东方,海派律师与产业协同发... 东方网消息:12月12日,“潮起东方十五五新机遇——海派律师与产业协同发展论坛”在上海陆家嘴隆重举行...
中美芯片政策松动之际,苏姿丰带... 苏姿丰率AMD高管团队“低调”到访联想总部,图片由知情人士提供 ,美国超威半导体公司(AMD)董事会...
政策红利叠加智能升级 辽宁口岸... “每年我都要来沈阳上3个月的课程,我爱人是俄罗斯人,240小时过境免签政策让她可以直接来这里跟我团聚...
以制度刚性强基固本 新修订的《中国共产党工作机关条例》为党的工作机关建设注入了强大动力。 坚守政治定位,要以党的创新理论...
事发长春!三名主播被起诉 三起网络主播合同纠纷在新业态案件巡回审判点“一揽子”化解 为进一步统一裁判尺度、提升审理效率,妥善化...
售后纠纷耗掉半条命?奇兵到家:... 今年3月,一个被网友称为“家电华佗”的家电维修师傅在短视频平台走红,其精湛技艺与朴实诚信收获了数百万...
姆巴佩劳资纠纷案胜诉 巴黎圣日... 中新网巴黎12月17日电 (孙羽婷)法国著名足球运动员姆巴佩与其前雇主巴黎圣日耳曼俱乐部劳资纠纷案于...
成功捐献非血缘造血干细胞纳入见... 齐鲁晚报·齐鲁壹点 李自强 刁明杰 12月16日,青岛召开发布会发布《青岛市红十字会条例》(以下称《...