可变参数函数简单解读(variadic function)
平时写代码接触最多函数大概就是 printf 函数了,printf 函数就是一个可变参数函数,第2个参数就是可变参数,第一个参数是格式化字符串。格式化字符串中的转换修饰符决定了可变参数的数量和类型。
int printf (const char *format, ...)
可变参数函数(variadic function):函数参数变量可变的函数。可变参函数包括至少一个强制参数(mandatory argument)+数量可变的可选参数(optional argument),强制性参数在前,可变参数用省略号(…)表示。
实现可变参数函数需要包含**<stdarg.h>**头文件,他提供需要用到的下列宏定义:
typedef char* va_list;
void va_start(va_list argptr, lastparam);
type va_arg(va_list argptr, type);
void va_end(va_list argptr);
void va_copy(va_list dest, va_list src);
- typedef char va_list;*:简单理解就是指向就是存放可变参数列表的指针,访问这个列表可以得到每一个可变参数。
第一步:定义函数,并用这个类型定义一个变量:
int m_printf(const char *f_str,...)
{
va_list p_list;
}
- void va_start(va_list argptr, lastparam);:第一个参数为va_list类型的变量,第2个参数为可变参的数量。此函数会做可变参数链表的初始化等工作。
第2步:用va_start初始化 p_list变量。format为printf函数的第一个参数。
int m_printf(const char *f_str,...)
{
va_list p_list;
va_start(p_list,f_str);
}
- type va_arg(va_list argptr, type);:第一个参数为va_list类型的变量,第2个参数为可变参数的类型。此函数会按照从左到右的顺序从可变参数列表里面pop出一项可变参数的值,然后p_list指针会指向下一个可变参数。
第3步:用va_arg获取可变参参数的值。根据参数类型,type需要设置为不同的类型。
int m_printf(const char *f_str,...)
{
va_list p_list;
int value;
char* chs;
va_start(p_list,f_str);
... ...
/* pop出一个int类型的值 */
value = va_arg(p_args,int);
/* pop出一个字符串 */
chs = va_arg(p_args,char*);
}
- void va_end(va_list argptr);:参数列表指针不需要被使用的时候需要调用此函数完成清理等工作。
最后一步调用va_end完成清理工作。
int m_printf(const char *f_str,...)
{
va_list p_list;
int value;
char* chs;
va_start(p_list,f_str);
... ...
/* pop出一个int类型的值 */
value = va_arg(p_args,int);
/* pop出一个字符串 */
chs = va_arg(p_args,char*);
... ...
va_end(p_args);
}
- 下面是一个简单的可变参数函数
add()
的实现代码:
/* num:表示可变参数的数量 */
int add(int num,...)
{
int sum,i;
va_list p_list;
int value;
sum = 0;
va_start(p_list