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

 1 #include <stdio.h>
 2 #include <stdarg.h>
 3 
 4 void WriteFormatted (FILE * stream, const char * format, ...)
 5 {
 6   va_list args;
 7   va_start (args, format);
 8   vfprintf (stream, format, args);
 9   va_end (args);
10 }
11 
12 int main ()
13 {
14    FILE * pFile;
15 
16    pFile = fopen ("myfile.txt","w");
17 
18    WriteFormatted (pFile,"Call with %d variable argument.\n",1);
19    WriteFormatted (pFile,"Call with %d variable %s.\n",2,"arguments");
20 
21    fclose (pFile);
22    getchar();
23    return 0;
24 }

va_list的实现原理,这里简单的介绍一下:

     在进程中,堆栈地址是从高到低分配的.当执行一个函数的时候,将参数列表入栈,压入堆栈的高地址部分,然后入栈函数的返回地址,接着入栈函数的执行代码,这个入栈过程,堆栈地址不断递减.

     总之,函数在堆栈中的分布情况是:地址从高到低,依次是:函数参数列表,函数返回地址,函数执行代码段.堆栈中,各个函数的分布情况是倒序的.即最后一个参数在列表中地址最高部分,第一个参数在列表地址的最低部分.

     而上面用到的几个看似函数的函数,其实是宏,它们的作用就是获取函数的参数列表的地址,它们的定义如下:

1   #define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )
2   #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) //第一个可选参数地址
3   #define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) //下一个参数地址
4   #define va_end(ap) ( ap = (va_list)0 ) // 将指针置为无效

 

posted @ 2012-12-19 22:58  邵贤军  阅读(451)  评论(0编辑  收藏  举报