一、可变参数的简单写法
见如下代码:
void function(int a, ...) {
}
这是一个最简单的可变参数的方法。
在传递实参时,可以在 function 中添加多个整数类型。
如下:
function(3);
function(3, 4);
function(3, 4, 5);
function(3, 4, 5, 6);
function(3, 4, 5, 6, 7);
function(3, 4, 5, 6, 7, 8);
这里传递多少实参都是可以的。
二、如何操作可变参数的值
[方法一] 使用stdarg.h中的三个宏
#include <iostream>
#include <stdarg.h>
using namespace std;
void function(int count, ...) {
va_list parameters; // 声明一个va_list变量
va_start(parameters, count); // 初始化,count为形参的个数,所以需要提前知道形参的个数
for (int i = 0; i < count; i++) {
int parameter = va_arg(parameters, int); // 取值
cout << "parameter:" << parameter << endl;
}
va_end(parameters); // 清理内容
}
int main()
{
function(9, 9, 8, 7, 6, 5, 4, 3, 2, 1);
return 0;
}
打印结果是:
parameter:9
parameter:8
parameter:7
parameter:6
parameter:5
parameter:4
parameter:3
parameter:2
parameter:1
使用步骤是:
(1)导入stdarg.h
#include <stdarg.h>
(2)定义一个含有可变参数的方法
void function(int count, ...) {
}
count为后面参数的个数,不包括自己。也就是说,function方法的形参个数是:count + 1
(3)声明一个va_list变量
va_list parameters; // 声明一个va_list变量
(4)初始化
va_start(parameters, count); // 初始化,count为形参的个数,所以需要提前知道形参的个数
(5)取值
int parameter = va_arg(parameters, int); // 取值
取值时,必须指明取值类型。
(6)清理内容
va_end(parameters); // 清理内容
(7)实参的传递
function(count, 5, 4, 3, 2, 1);
代码中,function的第一个实参是va_list的长度,count的不同取值决定了输出结果:
count = 0 ------------ 没有输出结果
count = 1 ------------ 输出结果:5
count = 2 ------------ 输出结果:5,4
count = 3 ------------ 输出结果:5,4,3
count = 4 ------------ 输出结果:5,4,3,2
count = 5 ------------ 输出结果:5,4,3,2,1
在使用va_start初始化时,第二个参数是parameters的长度,function参数的数量不是固定的,是变化的。
parameters的长度必须和可变参数的数量一致,如果不一致,容易导致数据的紊乱;
比如:
function(6, 5, 4, 3, 2, 1);
function除了第一个参数之外,其它参数都是可变参数,当执行初始化方法va_start时,可变参数将存入parameters中,与此同时一起被初始化的还有可变参数的数量。
当初始化传入的数量与实际可变参数数量不一致时,输出的实际结果可能和预想的不一致。
当传入的数量大于实际可变参数数量时,输出结果将会异常。
function(6, 5, 4, 3, 2, 1)的输出结果为:
parameter:5
parameter:4
parameter:3
parameter:2
parameter:1
parameter:-858993460
parameters的长度为6,但是只有5个值。
另外,可变参数可能不都是一个数据类型,它们有可能存在多种数据类型,比如:
#include <iostream>
#include <stdarg.h>
using namespace std;
/*
charCount:字符串类型参数的数量
intCount:整型参数的数量
*/
void function(int count, ...) {
va_list parameters; // 声明一个va_list变量
va_start(parameters, count); // 初始化,count为形参的个数,所以需要提前知道形参的个数
for (int i = 0; i < count; i++) {
char* charParameter = va_arg(parameters, char*); // 字符串取值
int intParameter = va_arg(parameters, int); // 整型取值
cout << "字符串:" << charParameter << endl;
cout << "整型:" << intParameter << endl;
}
va_end(parameters); // 清理内容
}
int main()
{
function(3, "张三", 4, "李四", 2, "王五", 1);
return 0;
}
输出结果是:
字符串:张三
整型:4
字符串:李四
整型:2
字符串:王五
整型:1
[方法二] 使用initializer_list标准库类型
演示代码如下:
#include <iostream>
#include <initializer_list>
using namespace std;
void function(initializer_list<int> list) {
for (auto ptr = list.begin(); ptr != list.end(); ptr++) {
cout << "输出数字:" << *ptr << endl;
}
}
int main()
{
function({3, 4, 5, 1});
return 0;
}
输出结果为:
输出数字:3
输出数字:4
输出数字:5
输出数字:1
该方法不需要指定list的长度,所以比方法一更加安全。在实际开发中,应该选择方案二。
使用initializer_list需要注意的是:
(1)元素必须具有相同的数据类型;
(2) initializer_list在C++11才被引入;
(3)传递实参时,参数需要放在{}(大括号)内;
[本章完...]












网友评论