linux C 可变参数类型va_list
可变函数参数,会用到va_list系列宏,在C中用于定义可变参数列表,包含可变参数信息。
常用的va_list系列宏
包含:
- va_start(ap, last)宏:初始化可变参数列表;
- va_arg(ap, type)宏:返回下一个参数;
- va_copy(dest, src)宏:复制参数列表指针,将dest初始化为src;
- va_end(ap)宏:结束使用可变参数列表,会清空参数列表,置参数ap无效;
其声明如下:
#include <stdarg.h>
void va_start(va_list ap, last);
type va_arg(va_list ap, type);
void va_end(va_list ap);
void va_copy(va_list dest, va_list src);
例如,我们常用的C库函数printf,就用到了可变参数列表
#include <stdio.h>
int printf(const char *format, ...);
形参列表里的 "..."代表0个或多个参数。
将可变参数由“...”转换为va_list类型形式,
#include <stdarg.h>
int vprintf(const char *format, va_list ap);
va_list系列宏使用模式
对于自定义可变参数列表的函数,可用va_list系列宏,按如下模式对可变参数进行解析:
void func(type v, ...)
{
va_list(ap, v); // 定义一个指向个数可变的参数列表指针
va_start(ap, v); // 使指针ap指向函数参数列表的第一个可选参数,v是第一个可选参数之前的固定参数
while () {
type tmp = va_arg(ap, type); // 返回参数列表中指针ap所指的参数,返回类型为type,并使指针ap指向下一个参数
}
va_end(ap); // 清空参数列表,并置参数列表指针ap无效
}
例1:定义一个可变参数的求和函数
int sum(int v, ...)
{
int i = v;
int s = 0;
va_list ap;
va_start(ap, v);
while (i > 0) {
s += va_arg(ap, int);
i--;
}
// {
volatile int tmp = va_arg(ap, int); // tmp是未知值
printf("tmp = %d\n", tmp);
// } 用于测试
va_end(ap);
return s;
}
调用:
int main()
{
int s = sum(3,2,3,4);
printf("sum = %d\n", s);
return 0;
}
运行结果:
tmp = -1392657952
sum = 9
例2:定义一个自定义打印字符串函数
void my_print(const char *fmt, ...)
{
char *s = fmt;
va_list ap;
va_start(ap, fmt);
while (s != NULL) {
printf("%s\n", s);
s = va_arg(ap, char *);
}
va_end(ap);
}
调用:
int main()
{
my_print("hello", "yes", "no");
return 0;
}
运行结果:
hello
yes
no
本文作者:明明1109
本文链接:https://www.cnblogs.com/fortunely/p/16093933.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
2021-04-02 Linux 系统编程学习笔记 - 终端、作业控制与守护进程