要使用可变参数函数
#include <stdarg.h>
需要包含这个头文件
这个头文件是系统的头文件,在linux内核中没有找到这个文件
VC6.0中包含这个头文件
这里面定义了一个重要变量和三个重要的宏
变量 va_list 定义指向参数的指针
宏:
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end(ap) ( ap = (va_list)0 )
_INTSIZEOF这个宏是前面三个宏的一个重要基础,这是用于堆栈对齐的,参数一定大于等于整数倍的堆栈大小,堆栈一般用int类型定义
va_start(ap,v) v用于指向最后一个确定的参数,根据最后一个参数的大小确定,ap所指向的位置,ap指向可变参数的第一个位置 + _INTSIZEOF(v)就是+v所占堆栈大小
va_arg(ap,t) t是一种类型 将ap这个地址,转换成指向这种类型变量的指针再取值
返回值是一个t变量的值,下图中返回一个char*变量的值
ap变成了指向下一个参数的指针,该宏整体还是当前的参数
当需要使用下一个参数时 ap此时就已经指向当前的参数了
&i为0x0012ff2c arg_ptr为0x0012ff30
va_end(ap)
从某个宏来看是将ap指针赋值为NULL
网上说需要将
va_start 和va_end成对使用
不同的硬件架构和软件环境对以上三个变量的定义是不同的
网上摘抄的实验代码
#include <stdio.h>
#include <stdarg.h>
void simple_va_fun(int i,...)
{
va_list arg_ptr;
char* j=0;
va_start(arg_ptr,i);
//j=va_arg(arg_ptr,char *);//和下一句等效
j = *((char **)arg_ptr);
va_end(arg_ptr);
printf("%d %s\n",i,j);
return;
}
int main()
{
simple_va_fun(100);
simple_va_fun(100,"hello!\n");
}