<stdarg.h> 省略号的使用
<stdarg.h>
//argument 自变量(函数)
//用于面向用户的函数(自行输入)
//是一个链表,设计的很好的链表
给函数输入参数时,需要设定参数个数和类型;
使用结构体作为输入参数时,也需要给结构体赋值;
所以,有没有办法进行 任意类型 任意数量 的参数输入呢?
在C的标准库函数中,提供了<stdarg.h>的头文件
载入后便可以使用C中的省略号'...',进行宽泛的输入
使用
对于文件使用->标识符/打开/使用/关闭
标识符->FILE *fd;
打开->fd=fopen();
使用->fread/fwrite(fd);
关闭->fclose(fd);
对于省略号也同样如此
//作用:多数相加
int my_add(int num,...){};//省略号//必须是 , + ...
va_list mytab;//标识符
va_start(arg_ptr,num);//开始//不用赋值
va_arg(arg_ptr,int);//使用//以 int类型 读取
va_end(arg_ptr);//结束
函数定义
va_list//适用va_start/arg/end函数存储信息的类型
void va_start(va_list ap, last_arg)//last_arg函数的最后一个固定参数
type va_arg(va_list ap, type)//type 输出的类型
void va_end(va_list ap)
例子:
//1.int类型 未定数量 的加法函数
//number=my_add(1,2,3,4,5,0);//number=15
int my_add(int num,...){
int sum=0;
sum+=num;
va_list arg_ptr;
int num_s;
va_start(arg_ptr,num);
do{
num_s=va_arg(arg_ptr,int);
sum+=num_s;
}while(num_s != 0);//输入0 则退出
va_end(arg_ptr);
return sum;
}
//2.printf()的实现
//一个链表构成的栈
static char sprint_buf[2408];
int printf(const char *fmt, ...)
{
va_list args;
int n;
// 第一个可变形参指针
va_start(args, fmt);
// 根据字符串fmt,将对应形参转换为字符串,并组合成新的字符串存储在sprint_buf[]缓存中,返回字符个数。
n = vsprintf(sprint_buf, fmt, args);
//c标准要求在同一个函数中va_start 和va_end 要配对的出现。
va_end(args);
// 调用相关驱动接口,将将sprintf_buf中的内容输出n个字节到设备,
// 此处可以是串口、控制台、Telnet等,在嵌入式开发中可以灵活挂接
if (console_ops.write)
console_ops.write(sprint_buf, n);
return n;
}
原理
在<stdarg.h>文件中,定义了变量类型 va_list 和三个宏
这三个宏可用于在参数个数未知(即参数个数可变)时获取函数中的参数
可变参数的函数通在参数列表的末尾是使用省略号(,...)定义的
typedef char *va_list;
typedef int acpi_native_int;
//入栈4字节对齐//出栈4字节对齐// 4字节对齐
#define _AUPBND (sizeof (acpi_native_int) - 1)
#define _ADNBND (sizeof (acpi_native_int) - 1)
#define _bnd(X, bnd) (((sizeof (X)) + (bnd)) & (~(bnd)))
//第一个可变形参指针
#define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))
//按照4字节对齐取下一个可变参数,并且更新参数指针
#define va_arg(ap, T) (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))
//与va_start成对,避免有些编译器告警
#define va_end(ap) (void) 0//结束,清空链表
学习引用:
部分基础概念
stdarg.h头文件源代码分析
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!