C/C++可变参数

在C/C++中会遇到需要定义使用可变参数的函数,例如printf就是,他的格式就是int printf(const char *format,...),对于这样类型的函数,他的实现实际上就是从format格式的指针指向的空间中读取可变参数的类型,然后根据可变参数的首地址读取相应的可变参数值

他的具体实现需要借助于3个宏实现(为了方便理解,以函数声明方式显示):

  • void va_start(va_list ap,last);//获取可变参数开始的首地址
  • type va_arg(va_list ap,type);//根据type参数类型获取实参值返回
  • void va_end(va_list ap);//将可变参数指针归NULL

其中va_list实际就是void*类型:

#define va_list                   void *  
#define va_start(ap,last)   (ap = ((va_list)&last+sizeof(va_list)))  
#define va_arg(ap,type)    (*(type*)((ap += sizeof(type)) - sizeof(type)))  
#define va_end(ap)           (ap = (va_list)0)  

具体流程如下:

1.定义变量ap,它用来指向可变参数的首地址

va_list ap;

2.获取可变参数的首地址并赋值给ap

va_start(ap,format);

3.从format中获取参数类型type

根据format中的特殊关键字符获取type,例如printf中的“%d”、“%x”、“%s”、“%02x”等。

4.根据获取到的参数类型从ap中获取实参

type arg;
arg = va_arg(ap,type);

5.循环直到将format中的关于类型的特殊字符读取完结束

直到ap取完,例如printf中format == NULL表示字符串取完。