上面这种方法对函数参数的入栈顺序有限制,必须从右向左入栈,这是为什么pascal调用方式不能实现printf的原因,并且函数形参都要通过栈来传递,这对有些编译器为了优化处理,函数参数通过寄存器来传递,从而不满足要求。鉴于次,本文采用C++的默认形参实现可变参数的方法,没有上面的这些限制,下面是实现代码:

#include <stdio.h>
enum {
  ptChar,
  ptInt,
  ptFloat,
  ptDouble,
 };
void printSum(unsigned long paramType,
     void *arg1 = NULL,
     void *arg2 = NULL,
     void *arg3 = NULL,
     void *arg4 = NULL,
     void *arg5 = NULL,
     void *arg6 = NULL,
     void *arg7 = NULL,
     void *arg8 = NULL,
     void *arg9 = NULL,
     void *arg10 = NULL)
{
 void *arg[10] = {
  arg1,
  arg2,
  arg3,
  arg4,
  arg5,
  arg6,
  arg7,
  arg8,
  arg9,
  arg10,
 };
 switch(paramType)
 {
 case ptChar:
  {
   int sum = 0;
   for (int i = 0; i < 10; i++)
   {
    if (arg[i] != NULL)
    {
     char *pValue = (char *)arg[i];
     sum += *pValue;
    }
    else
     break;
   }
   printf("%d ", sum);
  }
  break;
 case ptInt:
  {
   int sum = 0;
   for (int i = 0; i < 10; i++)
   {
    if (arg[i] != NULL)
    {
     int *pValue = (int *)arg[i];
     sum += *pValue;
    }
    else
     break;
   }
   printf("%d ", sum);
  }
  break;
 case ptFloat:
  {
   float sum = 0;
   for (int i = 0; i < 10; i++)
   {
    if (arg[i] != NULL)
    {
     float *pValue = (float *)arg[i];
     sum += *pValue;
    }
    else
     break;
   }
   printf("%f ", sum);
  }
  break;
  case ptDouble:
  {
   double sum = 0;
   for (int i = 0; i < 10; i++)
   {
    if (arg[i] != NULL)
    {
     double *pValue = (double *)arg[i];
     sum += *pValue;
    }
    else
     break;
   }
   printf("%f ", sum);
  }
  break;
 default:
  printf("unknowned type! ");
  break;
 }
}

void main()
{
 unsigned long paramType = ptChar;
 char a = 1, b = 2, c = 3;
 printSum(paramType, &a, &b, &c);

 paramType = ptInt;
 int ia = 1, ib = 2, ic = 3;
 printSum(paramType, &ia, &ib, &ic);

 paramType = ptFloat;
 float fa = 1, fb = 2, fc = 3;
 printSum(paramType, &fa, &fb, &fc);

 paramType = ptDouble;
 double da = 1, db = 2, dc = 3;
 printSum(paramType, &da, &db, &dc);
}