可变参数函数顾名思义,就是函数参数个数是未知的是可变的。
可变参数列表是通过宏来实现的,这些宏定义在stdarg.h 这个头文件中,这个头文件声明了一个类型va_list和三个宏——va_start , va_arg, va_end.
我们可以通过声明一个类型为va_list的变量,与这三个宏配合使用,从而访问参数的值,
用法:
比如定义一个可变参数函数
void print(char *fomt, ...)
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>