Example/* VA.C: The program below illustrates passing a variable
 * number of arguments using the following macros:
 *      va_start            va_arg              va_end
 *      va_list             va_dcl (UNIX only)
 */#include <stdio.h>
#define ANSI            /* Comment out for UNIX version     */
#ifdef ANSI             /* ANSI compatible version          */
#include <stdarg.h>
int average( int first, ... );
#else                   /* UNIX compatible version          */
#include <varargs.h>
int average( va_list );
#endifvoid main( void )
{
   /* Call with 3 integers (-1 is used as terminator). */
   printf( "Average is: %d\n", average( 2, 3, 4, -1 ) );   /* Call with 4 integers. */
   printf( "Average is: %d\n", average( 5, 7, 9, 11, -1 ) );   /* Call with just -1 terminator. */
   printf( "Average is: %d\n", average( -1 ) );
}/* Returns the average of a variable list of integers. */
#ifdef ANSI             /* ANSI compatible version    */
int average( int first, ... )
{
   int count = 0, sum = 0, i = first;
   va_list er;   va_start( er, first );     /* Initialize variable arguments. */
   while( i != -1 )
   {
      sum += i;
      count++;
      i = va_arg( er, int);
   }
   va_end( er );              /* Reset variable arguments.      */
   return( sum ? (sum / count) : 0 );
}
#else       /* UNIX compatible version must use old-style definition.  */
int average( va_alist )
va_dcl
{
   int i, count, sum;
   va_list er;   va_start( er );            /* Initialize variable arguments. */
   for( sum = count = 0; (i = va_arg( er, int)) != -1; count++ )
      sum += i;
   va_end( er );              /* Reset variable arguments.      */
   return( sum ? (sum / count) : 0 );
}
#endif
OutputAverage is: 3
Average is: 8
Average is: 0因为调用者知道传给函数多少个参数,所以他可以确定怎样清理堆栈,这样就可以实现可变参数了,你可以看看上边的例子

解决方案 »

  1.   

    pascal 调用由函数自身负责清除栈中的参数,cdecl由主调函数负责,所以
    cdecl调用可以实现变参,因为调用函数知道怎样清除栈中的参数,而pascal调用由函数自身负责就不可能变参了,因为函数不可能知道调用方串多少参数,所以不知道如何如何清理堆栈!
      

  2.   

    我也想问问__stdcall和__cdecl之间怎么转换啊?
      

  3.   

    __stdcall和__cdecl这类东东,一般你不用关心,只有在做dll或其它外部接口时,你才有必要注意两者声明之间的一致性。