可变参数函数顾名思义,就是函数参数个数是未知的是可变的。
可变参数列表是通过宏来实现的,这些宏定义在stdarg.h 这个头文件中,这个头文件声明了一个类型va_list和三个宏——va_start , va_arg, va_end.
我们可以通过声明一个类型为va_list的变量,与这三个宏配合使用,从而访问参数的值,
用法:
比如定义一个可变参数函数
void print(char *fomt, ...)
va_list : 声明一个变量//va_list arg;
va_start:初始化va_list声明的这个变量,它的第一个参数是va_list声明的变量另外一个参数是省略号前最后一个有名字的参数//va_start(arg,fomt);
初始化过程就是把参数列表的第一个参数给va_list声明的这个变量。
va_arg:我们就是通过这个来访问未知参数的,va_arg的一个参数是va_list声明的这个变量,另一个参数列表中下一个要接收的参数类型//va_arg(arg,char);
va_end:释放空间
下面我们就通过模拟printf这个函数,来具体了解。
#include<stdio.h>
#include<assert.h>
#include<stdarg.h>
void print(char *fomt, ...)
{
char *ch;
assert(*fomt);//断言
va_list arg;//定义arg
va_start(arg, fomt);初始化arg 即把可变参数列表中首个变量地址给arg
while (*fomt)
{
switch(*fomt)
{
case 'c':
putchar(va_arg(arg,char));//va_arg 获取参数列表中下一个未知参数,可以通过前面获取的字符判断下一个参数类型
break;
case 's':
/*puts(va_arg(arg, char*));*/ //字符串可以直接用puts()函数输出
ch = va_arg(arg, char*);//还可以定义一个指针变量接收获取的字符,从而用putchar()一个一个输出
while (*ch)
{
putchar(*ch);
ch++;
}
break;
default :
putchar(*fomt);
}
fomt++;
}
va_end(arg);//最后释放arg
}
int main()
{
print("val:s ccccc\n","hello", 'w', 'o', 'r', 'l', 'd');
system("pause");
return 0;
}
<span style="font-size: 14px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">在可变参数列表的访问过程中访问几个参数半途中止是可以的,但在一开始就想访问中间参数是做不到的。</span>