如何声明一个可变参数的函数
在无法给出所有传递给函数的参数的类型和数目时,可以使用省略号(…)指定函数参数表。有如下几种形式:
1 | void fun1(int a, double b, ...); //给出确定的几个参数,其他用省略号 |
举个例子:计算n个整数的和。
1 | - (int)test_n_number_add:(int)n, ... { |
va_list存在的两个隐患:
1.如何确定参数的类型。
没有其他办法,就是通过强制转换。va_arg就是把当前指针所指向的内容强制转换到指定类型。像printf函数还有个格式化参数来说明后面参数的类型。如果是自己写的,同样得事先约定好一套规则。
2.如何确定参数的个数。也就是参数结束标志。
也没有规定,同样得事先约定好一套规则。比如这里第一个固定参数说明了后续可变参数的个数。再比如求自然数的平方和,那么可以把负数和0作为它的结束标志。其他系统函数如scanf把接收到的回车符作为结束标志,大家熟知的printf对字符串的处理用’\0’作为结束标志。
由于上面的原因,对于可变参数的函数,外部调用者和实现者必须遵守共同的约定才行。可变参数的函数,一般在格式化函数中用的比较多。
NSLog 和 NSLogv
1 | FOUNDATION_EXPORT void NSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2) NS_NO_TAIL_CALL; |
NSLogv可以传入一个可变参数列表,而NSLog不能(废话)。
考虑这样一种情况:函数A接受可变参数,函数B也接受可变参数。A内部要调用函数B,那么怎么把可变参数传给B呢?那么就可以使用va_list先获取到可变参数列表,再传给B。
举例:
1 | - (void)test_nslog { |