返回值:成功返回输出的字节数(不包括后的’’),失败返回-1。
  vsprintf()与上面函数类似,只列出函数原型了:
  int vsprintf(
  char *buffer,
  const char *format,
  va_list argptr
  );
  还有一个int _vscprintf(const char *format, va_list argptr );可以用来计算vsprintf()函数中的buffer字符串要多少字节的空间。
  代码范例
  下面给出了自己实现的printf()函数(注1)与WriteLine()函数
int Printf(char *pszFormat, ...)
{
va_list   pArgList;
va_start(pArgList, pszFormat);
int nByteWrite = vfprintf(stdout, pszFormat, pArgList);
va_end(pArgList);
return nByteWrite;
}
int WriteLine(char *pszFormat, ...)
{
va_list   pArgList;
va_start(pArgList, pszFormat);
int nByteWrite = vfprintf(stdout, pszFormat, pArgList);
if (nByteWrite != -1)
putchar(' '); //注2
va_end(pArgList);
return (nByteWrite == -1 ? -1 : nByteWrite + 1);
}
  调用与printf()函数相同。
  再给出一个用可变参数来求和,遗憾的在C,C++中无法确定传入的可变参数的个数(printf()中是通过扫描'%'个数来确实参数的个数的),因此要么要指定个数,要么在参数的后要设置哨兵数值:
  设置哨兵数值:
const int GUARDNUMBER = 0; //哨兵标识
//变参参数的个数无法确定,在printf()中是通过扫描'%'个数,在这通过设置哨兵标识来确定变参参数的终止
int MySum(int i, ...)
{
int sum = i;
va_list argptr;
va_start(argptr, i);
while ((i = va_arg(argptr, int)) != GUARDNUMBER)
sum += i;
va_end(argptr);
return sum;
}
  可以这样的调用:   printf("%d ", MySum(1, 3, 5, 7, 9, 0));
  但不可以直接传入一个0:   printf("%d ", MySum(0)); //error
  指定个数:
int MySum(int nCount, ...)
{
if (nCount <= 0)
return 0;
int sum = 0;
va_list argptr;
va_start(argptr, nCount);
for (int i = 0; i < nCount; i++)
sum += va_arg(argptr, int);
va_end(argptr);
return sum;
}
  调用时第一个参数表示后面参数的个数如:
  printf("%d ", MySum(5, 1, 3, 5, 7, 9));
  printf("%d ", MySum(0));
  代码所用的头文件:
  #include <stdarg.h>
  #include <stdio.h>
  可变参数的使用方法远远不止上述几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃。
  可变参数的原形理涉及到调用函数时参数的入栈问题,这个下次再开一篇进行专门的探讨。
  注1. 网上有不用vfprintf()自己解析参数来实现printf()的,但很少能将功能做到与printf()相近(实际上能完全熟悉printf()的人已经不多,不信的话可以先看看《C陷阱与缺陷》了解printf()很多不太常用的参数,再去Microsoft Visual StudioVC98CRTSRC中查看OUTPUT.C对printf()的实现)。
  注2. 如果输出单个字符 putchar(ch)会比printf(“%c”, ch)效率高的多。在字符串不长的情况下,多次调用putchar()也会比调用printf(“%s ”, szStr);的效率高。在函数大量调用时非常明显。