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

相关内容

热门资讯

10岁孩子不幸溺亡,家长起诉4... 导 读 8月17日,“10岁孩子溺亡家长起诉其4名同伴”相关话题冲上热搜。五名不满12岁的孩子结伴戏...
新《徐州市集中供热条例》10月... 近日,经徐州市第十七届人民代表大会常务委员会第三十三次会议修订通过,江苏省第十四届人民代表大会常务委...
东莞金融市场周报:生益电子17... 本期看点:东莞市科技成果转化基金完成首投;东莞银行首家香港子行开业;生益电子新增投资17.5亿建设算...
降雨集中在今夜!青岛局部大雨或... 明天就要出伏了 但气温并未立即下行 “秋老虎”来了 ↓↓↓ 据中国天气网预报 大范围持续性高温闷热来...
我国首个法律垂直大模型发布;小... 2025 年 8 月 17 日IT之家热门新闻榜单: 没有自主系统 = 被卡脖子:上海交通大学教授夏...
2025年黑龙江省普通高等教育... 记者从黑龙江省教育厅获悉,目前,我省已建立了比较完善的高等教育阶段学生资助政策体系,为家庭经济困难学...
实证筑基智能落地 首个法律垂直... 8月16日,第五届“小包公杯”大学生法律实证分析征文比赛颁奖仪式在广州举行。活动同期发布我国首个法律...
杭州已连续出现14天高温天!接... 杭州市气象局发布最新消息:从8月3日起,杭州已经连续出现14天高温天(8月3日起至8月16日)!但接...
原创 盘... 最近再度带起律政剧风潮!接连不少有关律师职人剧接连开播!包括刚播毕大结局的《瑞草洞》、还有刚开播新剧...