当前位置: 首页 > news >正文

可变参数函数

可变参数函数

  • 一,什么可变参数函数?
  • 二,实现机制
    • 1,函数调用时的栈与栈帧
    • 2,可变参数实现机制

一,什么可变参数函数?

普通函数:
声明时参数个数和类型都固定好,比如 int add(int a, int b),只能接收两个 int。

可变参数函数:
在声明时只写固定的“前导”参数,后面用 … 表示还有不定数量、也不定类型的参数。

有点抽象,下面直接上例子

int my_printf(UART_HandleTypeDef *huart, const char *format, ...)
{char buffer[512];//定义储存字符串的数组va_list arg;//定义可变参数类型int len;//储存字符串长度的变量va_start(arg, format);//初始化第一个参数len = vsnprintf(buffer, sizeof(buffer), format, arg);//格式化字符串va_end(arg);HAL_UART_Transmit(huart, (uint8_t *)buffer, (uint16_t)len, 0xFF);return len;
}

这是我们串口发送时使用的函数,第一个形参固定了是一个UART的句柄(包含UART的所有信息),后面的参数可以改变如:

my_printf(&huart1,"Value=%d\n", 42);
my_printf(&huart1,"A=%d, B=0x%02X, C=%.2f\n", 10, 0x5A, 3.14);

这里应该理解了为什么串口所有可变参数函数了吧
接下来讲讲可变参数函数的具体实现机制

二,实现机制

在讲可变参数函数之前,我们要先了解函数调用时的栈

1,函数调用时的栈与栈帧

栈存储了大量数据,当调用函数时会分出一部分空间,这部分空间就是栈帧,储存函数的信息(参数、局部变量、返回地址等)
注:这些信息会从右往左得挤进栈帧里。可变变量会跟在固定变量后面进入栈帧

2,可变参数实现机制

1,va_list 指针类型,用于指向可变参数列表中的当前位置。
va_list:
指针类型,在原代码中。arg就是用来储存可变变量地址的宏,它得类型就是va_list.
在串口功能中,我们需要访问可变变量,完成传输,arg就是用来储存这些可变变量的。

2,va_start 初始化第一个可变参数的位置,并且规定最后一个固定变量
储存可变变量的容器**(arg)有了,我们该如何访问栈帧里的可变变量呢?
va_start会访问最后一个固定变量的位置,再直接规定下一个位置为第一个可变变量。
arg 会被初始化并指向可变参数的开始位置,方便后续通过 va_arg 获取每个参数。
因为我们前面说了,可变变量是紧跟着固定变量进的栈。

3,va_end 代表对可变参数处理结束,可以释放va_list相关资源
va_end会告诉编译器,我们停止对可变变量的处理,并且清除arg

http://www.xdnf.cn/news/695827.html

相关文章:

  • 74道Node.js高频题整理(附答案背诵版)
  • 记一次 Qwen3-0.6B 微调 内容提取
  • 让爱延续,共筑养老服务产业的美好未来
  • 二重积分 面积微元 微小矩形 dxdy 微小扇形 r * drdθ
  • 动静态库的制作
  • c++ 拷贝构造函数
  • JVM——Truffle:语言实现框架
  • 【机器学习基础】机器学习入门核心算法:朴素贝叶斯(Naive Bayes)
  • Spring AI 1.0 GA 深度解析:构建企业级AI应用的全栈实践指南
  • Linux的基本指令
  • vscode 终端 PATH 和python pip 不对
  • CSS (mask)实现服装动态换色:创意与技术的完美融合
  • HIS换代升级辅助脚手架:数据清洗、人员信息标准化、电子病历接口标准化、多模态影像接口标准化
  • 三级联动获取省市区
  • 8种常见数据结构及其特点简介
  • 排查Oracle文件打开数过多
  • JAVA 笔记
  • 【超详细教程】零基础本地部署DeepSeek-Coder-v2 16B!Ollama+GPU加速,100%跑通!
  • CCLINKIE转PROFINET:让执行器“丝滑”入网!
  • 脑机新手指南(一):BCILAB 脑机接口工具箱新手入门指南
  • 从新安全法到隐患判定标准:特种设备证件管理政策全梳理
  • vben-admin 2.8.0 版本修改 axios响应处理逻辑
  • MySQL:零基础入门(狂神版)
  • PyTorch安装Cuda版本选择
  • WMS系统选型与实施避坑手册
  • HarmonyOS 5 应用开发导读:从入门到实践
  • C++STL——map与set的使用
  • “顶点着色器”和“片元着色器”是先处理完所有顶点再统一进入片元阶段,还是一个顶点处理完就去跑它的片元?
  • 上传头像upload的简易方法,转base64调接口的
  • Spring AI 系列之使用 Spring AI 开发模型上下文协议(MCP)