『C/C++』可变参数
从 scanf() 和 printf() 讲起
在使用 scanf()
和 printf()
时,你会发现一个奇怪的现象,它的参数个数是不确定的,格式化字符串中有多少个%
,后面就要跟多少个参数
1 | printf("%d",a); |
但在我们一般的印象中,一个函数在被声明时,它的参数个数就固定了,不能改变
让我们在 stdio.h
中找到 scanf()
的定义:
1 | int scanf(const char *__format, ...) |
接受参数怎么有个省略号?还可以这样写吗?
这便牵扯到可变参数
可变参数的头文件
我们在使用可变参数时,需要引入 stdarg.h
头文件
在 stdarg.h
中,有一个数据类型,四个宏
类型 | 描述 |
---|---|
va_list |
用来保存宏 va_arg 与宏 va_end 所需信息 |
宏 | 描述 |
---|---|
va_start(va_list,省略号的前一个参数) |
使 va_list 指向起始的参数 |
va_arg(va_list,参数类型) |
检索参数并返回 |
va_end(va_list) |
释放 va_list 的内存空间 |
va_copy(va_list, va_list) |
拷贝 va_list 的内容,va_copy(va2, va1) 作用为拷贝 va1到 va2 |
如何使用
- 定义一个函数,最后一个参数为省略号,省略号前面可以有任意个参数,但至少要有一个
- 声明一个
va_list
类型变量用于承载参数列表 - 使用
va_start()
初始化va_list
- 多次使用
va_arg()
依次获取参数列表里的值,每执行一次就返回一个参数(通过类型自动跳到下一个参数的位置) - 使用宏
va_end()
来回收va_list
变量
注意:没有机制可以确定省略号里一共传递了多少个参数,以及他们各自的数据类型( va_arg()
会一直往后跳,即使已经超出了总参数的个数,它也不知道)
为了解决这个问题,通常有三种方法
- 在省略号前传入一个整型,表示后面参数的总数(总数变量法)
- 使用一个特定的标识符来确定参数的结尾,如传递一串
int
,并使用-1
表示数据结束(标识符法) - 在省略号前传入一个格式化字符串,通过字符串确定参数的数量以及各自的类型(格式化字符串法,类似
scanf()
和printf()
)
样例
1 |
|
1 |
|
不想写,评论区有大佬的话可以写一个
参考资料:
评论
GiscusTwikoo