您的位置:首页 > 其它

130.可变参数或不定参数(va_list、va_start、va_arg、va_end)

2018-01-19 16:12 501 查看

简述

我这里所说的可变参数或不定参数是指, 方法中的某个形式参数可以接收多个参数(不确定个数的参数)。就比如, 下面的一些系统的方法:

[NSArray arrayWithObjects:@"first", @"second", @"third"];
[[UIAlertView alloc] initWithTitle:@"title" message:@"message" delegate:nil cancelButtonTitle:@ otherButtonTitles:@"first", @"second", @"third", nil];


// Method Reference

+ (instancetype)arrayWithObjects:(ObjectType)firstObj, ... NS_REQUIRES_NIL_TERMINATION;
- (instancetype)initWithTitle:(nullable NSString *)title message:(nullable NSString *)message delegate:(nullable id /*<UIAlertViewDelegate>*/)delegate cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitles:(nullable NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION


以上这两个方法都是系统的方法,
NSArray
方法中的
firstObj
UIAlertView
方法中的
otherButtonTitles
都是可变参数。

实现可变参数的方法

自定义一个方法
printMessages:
实现可变参数:

- (void)printMessages:(nullable NSString *)messages, ... NS_REQUIRES_NIL_TERMINATION {
if (messages) {
// 取出第一个参数(这是固定参数)
NSLog(@"固定参数: %@", messages);
// 定义一个参数列表指针
va_list args;
// 存放所取参数的指针
NSString *arg;
// 初始化va_list变量
va_start(args, messages);
// 取出va_list中存储的可变参数(不包含固定参数), 取出后args指向参数列表中的下一个参数
while ((arg = va_arg(args, NSString *))) {
NSLog(@"可变参数: %@", arg);
}
// 清空参数列表,并将va_list的指针置为NULL
va_end(args);
}
}


调用方法:

[self printMessages:@"first", @"second", @"third", nil];


打印结果:

固定参数: first

可变参数: second

可变参数: third

实现可变参数的原理

在上面的代码中, 读取可变参数的过程其实就是在堆栈中,使用指针, 遍历堆栈段中的参数列表, 从低地址到高地址一个一个地把参数内容读出来的过程。

归根到底还是通过
va_list
va_start
va_arg
va_end
这四个宏的功能来实现的。它们就是C语言中用来解决变参问题的一组宏。

它们的具体作用如下:

va_list
: 用于获取不确定个数的参数, 保存宏
va_start
va_arg
va_end
所需信息的一种类型。为了访问可变参数列表中的参数,必须声明一个
va_list
类型的指针。

va_start
: 初始化
va_list
,获取可变参数列表的第一个参数的地址。初始化结果供宏
va_arg
va_end
使用。

va_arg
: 获取可变参数的当前参数,返回指定类型并将指针指向下一参数

va_end
: 清空
va_list
可变参数列表,并该指针置为NULL

Demo下载地址:

Demo集合

拓展资料:

va_listva_startva_argva_end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐