您的位置:首页 > 编程语言 > C语言/C++

[C++基础]040_可变参数va_list的一段示例代码

2012-12-19 22:58 381 查看
#include <stdio.h>
#include <stdarg.h>

void WriteFormatted (FILE * stream, const char * format, ...)
{
va_list args;
va_start (args, format);
vfprintf (stream, format, args);
va_end (args);
}

int main ()
{
FILE * pFile;

pFile = fopen ("myfile.txt","w");

WriteFormatted (pFile,"Call with %d variable argument.\n",1);
WriteFormatted (pFile,"Call with %d variable %s.\n",2,"arguments");

fclose (pFile);
getchar();
return 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 ) // 将指针置为无效
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: