1、可变参数
可变参数是指函数带有可变数量的参数,而不是预定义数量的参数。函数需要固定数量的强制参数(mandatory argument),后面是数量可变的可选参数(optional argument)。C语言中最常用的可变参数函数例子是 int printf(const char *format, ...)
。
参数列表的格式是强制性参数在前,后面跟着一个逗号和省略号(...
),这个省略号代表可选参数。
例如,
#include// 函数add() 计算可选参数之和// 参数:第一个强制参数指定了可选参数的数量,可选参数为double类型// 返回值:和值,double类型double add( int n, ... ){ int i = 0; double sum = 0.0; va_list argptr; va_start( argptr, n ); // 初始化argptr for ( i = 0; i < n; ++i ) // 对每个可选参数,读取类型为double的参数, sum += va_arg( argptr, double ); // 然后累加到sum中 va_end( argptr ); return sum;}int main (){ printf("多个数相同的结果是%f", add(6,3,4,6,7,8,9)); return(0);}
注意:函数 add()
最后一个参数写成省略号,即三个点号(...),省略号之前的那个参数是 int n
,代表了要传递的可变参数的总数。为了使用这个功能,需要使用 stdarg.h
头文件,该文件提供了实现可变参数功能的函数和宏。
#define _INTSIZEOF(n) ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
#define va_arg(ap,type) ( *(type *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end(ap) ( ap = (va_list)0 )
1)定义一个函数,最后一个参数为省略号,省略号前面可以设置自定义参数。
在函数定义中创建一个 va_list
类型变量,该类型是在 stdarg.h
头文件中定义的。
2)使用 int 参数和 va_start
宏来初始化 va_list
变量为一个参数列表。宏 va_start
是在 stdarg.h
头文件中定义的。
3)使用 va_arg
宏和 va_list
变量来访问参数列表中的每个元素。
4)使用宏 va_end
来清理va_list
变量的内存。
5)宏va_start
通过该宏定义可以获取到可变参数表的首地址,并将该地址赋给指针ap
。
6)宏va_arg
通过该宏定义可以获取当前ap
所指向的可变参数,并将指针ap
指向下一个可变参数。注意,该宏的第二个参数为类型。
7)宏va_end
通过该宏定义可以结束可变参数的获取。
例如,
#include#include void myprintf(const char *format, ...){ va_list ap; char c; va_start(ap, format); while (c = *format++) { switch(c) { case 'c': { char ch = va_arg(ap, int); putchar(ch); break; } case 's': { char *p = va_arg(ap, char *); fputs(p, stdout); break; } default: putchar(c); } } va_end(ap);}int main(void){ myprintf("c\ts\n", '1', "hello"); return 0;}