Stdarg.h

声明不定参数函数

不定参数函数的参数数量是可变动的，它使用省略号来忽略之后的参数。例如printf函数一般。代表性的声明为:
int check(int a, double b, ...);
不定参数函数最少要有一个命名的参数，所以
char *wrong(...);
在C是不被允许的。在C，省略符号之前必须要有逗号；在C++，则没有这种强制要求。
（虽然在C++中，这样的声明是合理的，但是这种写法，因为没有已命名的参数，使得va_start没办法抓到动态参数的正确起始点。）

定义不定参数函数

使用与声明时相同的语法来定义:
long func(char, double, int, ...);long func(char a, double b, int c, ...){
    /* ... */}
在旧形式中可能会出现较省略的函数定义:
long func();long func(a, b, c, ...)
    char a;
    double b;{
    /* ... */}

类型安全性

有些C的实现，提供了对不定参数的扩展，允许编译器检查适当的格式化字符串及标志(sentinels)的使用。如果没有这种扩展，编译器通常无从检查传入函数的未命名参数是否为所预期的数据类型，也不能转换它们为所需要的数据类型。因此，必须小心谨慎以确保正确性，因为不匹配的数据类型降到导致未定义行为(Undefined behavior)。例如，如果传递空指针，不能仅仅写入NULL（可能实际定义为0），还要转化为（cast）适当的指针类型。另一个考虑是未命名参数的默认的类型提升。float将会自动的被转换成double‧同样的比int(整数)更小容量的参数数据类型将会被转换成int或者unsigned int‧函数所接收到的未命名参数必须预期将被数据类型提升。

例子

#include <stdio.h>#include <stdarg.h>void printargs(int arg1, ...) /* 輸出所有int型態的參數，直到-1結束 */{
  va_list ap;
  int i;

  va_start(ap, arg1); 
  for (i = arg1; i != -1; i = va_arg(ap, int))
    printf("%d ", i);
  va_end(ap);
  putchar('\n');}int main(void){
   printargs(5, 2, 14, 84, 97, 15, 24, 48, -1);
   printargs(84, 51, -1);
   printargs(-1);
   printargs(1, -1);
   return 0;}
这个程序产生输出:
5 2 14 84 97 15 24 48
84 51

1

varargs.h

POSIX定义所遗留下的头文件varargs.h，它早在C标准化前就已经开始使用了且提供类似stdarg.h的机能。MSDN明确指出这一头文件已经过时，完全被stdarg.h取代。这个头文件不属于ISO C的一部分。文件定义在单一UNIX规范的第二个版本中，简单的包含所有C89 stdarg.h的机能，除了:不能使用在标准C较新的形式定义；你可以不给予参数(标准C需要最少一个参数)；与标准C运作的方法不同，其中一个写成：
#include <stdarg.h>int summate(int n, ...){
    va_list ap;
    int i = 0;

    va_start(ap, n);
    for (; n; n--)
        i += va_arg(ap, int);
    va_end(ap);
    return i;}
或比较旧式的定义:
#include <stdarg.h>int summate(n, ...)
    int n;{
    /* ... */}
以此调用
summate(0);summate(1, 2);summate(4, 9, 2, 3, 2);

使用varargs.h的函数为:
#include <varargs.h>summate(n, va_alist)
    va_dcl /* 這裡沒有分號! */{
    va_list ap;
    int i = 0;

    va_start(ap);
    for (; n; n--)
        i += va_arg(ap, int);
    va_end(ap);
    return i;}
以及相同的调用方法。
varargs.h因为运作的模式需要旧数据类型的函数定义。