<stdarg.h>主要用于参数个数未知(即参数个数可变)时获取函数中的参数。
va_list类型,
typedef char *va_list;
_INTSIZEOF(n)变量,
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
//保证字节数为int的整数倍
va_start宏,获取可变参数列表的第一个参数的地址(list是类型为va_list的指针,param1是可变参数最左边的参数):
#define va_start(list,param1) ( list = (va_list)¶m1+ _INTSIZEOF(param1) )
void test(char *para1,char *param2,char *param3, char *param4)
{
//此时test函数的栈空间布局:
//由高处往低处生长
va_list list;
......
va_start(list,param1);
......
return;
}
//栈空间的整体布局与list指针指向如下
va_arg宏,获取可变参数的当前参数,返回指定类型并将指针指向下一参数(mode参数描述了当前参数的类型):
#define va_arg(list,mode) ( (mode *) ( list += _INTSIZEOF(mode) ) )[-1]
va_end宏,清空va_list可变参数列表:
#define va_end(list) ( list = (va_list)0 )
#include <stdio.h>
#include <stdarg.h>
void var_test(const char *format, ...)
{
va_list list;
va_start(list,format);
char *ch;
while(1)
{
ch = va_arg(list, char *);
if(strcmp(ch,"") == 0)
{
printf("\n");
break;
}
printf("%s ",ch);
}
va_end(list);
}
int main()
{
var_test("test","this","is","a","test","");
return 0;
}
与va相关的打印函数
int vprintf(const char *format, va_list ap);
int vfprintf(FILE *stream, const char *format, va_list ap);
int vdprintf(int fd, const char *format, va_list ap);
int vsprintf(char *str, const char *format, va_list ap);
int vsnprintf(char *str, size_t size, const char *format, va_list
#include <stdio.h>
#include <stdarg.h>
char buf[1024];
void var_test(const char *format, ...)
{
va_list list;
va_start(list, format);
int len;
len = vsprintf_s(buf, format, list);
va_end(list);
}
int main()
{
var_test("%s %s %d %s","this", "is", 1, "test");
cout << buf << endl;
return 0;
}
参数个数未知的函数define
//最简单的定义
#define my_print1(...) printf(__VA_ARGS__)
//搭配va_list的format使用
#define my_print2(format, ...) printf(format, __VA_ARGS__)
//##:若可变参数的个数为0时
//这里printf参数列表中的的##会把前面多余的","去掉
//否则会编译出错,建议使用后面这种,使得程序更加健壮。
#define my_print3(format, ...) printf(format, ##__VA_ARGS__)