变长参数列表
用到了以下三个宏(第四个宏只是与之相关,并没用到):
void va_start(va_list arg_ptr, prev_param);
type va_arg(va_list arg_ptr, type);
void va_end(va_list arg_ptr);
void va_copy(va_list d, va_list s);
va_list:用来保存宏va_start、va_arg和va_end所需信息的一种类型。为了访问变长参数列表中的参数,必须声明va_list类型的一个对象,它的定义:
typedef char * va_list;
va_start:访问变长参数列表中的参数之前使用的宏,它初始化用va_list声明的对象,初始化结果供宏va_arg和va_end使用;
va_arg: 展开成一个表达式的宏,该表达式具有变长参数列表中下一个参数的值和类型。每次调用va_arg都会修改用va_list声明的对象,从而使该对象指向参数列表中的下一个参数;
va_end:该宏使程序能够从变长参数列表用宏va_start引用的函数中正常返回。
下面是示例代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdarg.h> 4 5 /* ANSI标准形式的声明方式,括号内的省略号表示可选参数 */ 6 int demo(char *msg, ...) 7 { 8 va_list arg_list = NULL; // 定义保存函数参数的结构,实际上是字符串 9 int count = 0; // 纪录参数个数 10 char* para = NULL; // 存放取出的字符串参数 11 12 /* argp指向传入的第一个可选参数,msg是最后一个确定的参数 */ 13 va_start(arg_list, msg); 14 15 while (1) 16 { 17 /* 取出当前的参数,类型为char* */ 18 /* 一般自定的变长参数函数,变长部分类型都是统一的 */ 19 /* 如果想编写类似与printf这种参数类型不固定的变长参数的函数 */ 20 /* 那么就需要在参数中说明参数的类型,例如%d表示整数,%s表示字符串 */ 21 para = va_arg(arg_list, char *); 22 23 /* 采用空串指示参数输入结束,这是必须,函数需要知道参数列表的结尾 */ 24 if (0 == strcmp(para, "\0")) 25 { 26 break; 27 } 28 29 printf("Parameter #%d is: %s\n", count, para); 30 count++; 31 } 32 33 /* 完成清理工作 */ 34 va_end(arg_list); 35 36 return 0; 37 } 38 39 int main(void) 40 { 41 demo("DEMO", "This is a demo!", "You are so cute ^_^!", "\0"); 42 43 return 0; 44 } 45 46 /* 47 输出结果: 48 Parameter #0 is: This is a demo! 49 Parameter #1 is: You are so cute ^_^! 50 */
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用