C可变参数列表
//
// main.c
// test
//
// Created by cbd on 01/01/2017.
// Copyright © 2017 cbd. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
int64_t sum(int c_num, ...);
int main(int argc, const char * argv[]) {
int64_t result = sum(3, 1,2,3);
//int printf(const char * __restrict, ...) __printflike(1, 2);
printf("sum: %lld\n", result);
return EXIT_SUCCESS;
}
/**
任意多个数相加求和
@param c_num 加数个数
@param ... 加数
@return 和
*/
int64_t sum(int c_num, ...) {
va_list addend_list;
int64_t sum = 0;
va_start(addend_list, c_num);
for (int i = 0; i< c_num; i++) {
sum += va_arg(addend_list, int);
}
va_end(addend_list);
return sum;
}
小结
va_list/va_start/va_arg/va_end 配合使用。
va_list 用来声明一个变量,此处即addend_list。
该变量其实是个指针,由va_start来初始化,第一个参数为该变量,第二个参数为函数声明中 ...
前面的一个变量。
也就是所函数原型中至少有一个类型和名称都确定的参数。
依次调用 va_arg
来获取 可变参数中的具体参数。va_arg 要求明确知道总共有几个参数和每个参数的类型。但参数类型只会是int或double,此时会发生缺省参数类型提升。
当调用一个没有声明原型的函数时,会发生默认参数提升。
这里 ...
也其中一种情况,因为编译器并不知道入参到底是什么类型,和没有函数声明同样对待。
可变参数列表最典型的应用就是 printf("%d\n",129);
。
"%d\n"
就是第一个确定的参数, %d
用来标示后面的参数要用什么类型来解释。
所以该类型必须是明确的准确的,也就是『类型不安全』的,因为prinf不可能再根据其他信息猜测更多。