C语言不定参数

C语言不定参数主要使用下面几个宏。实现本质为一个arg_ptr的指针移动,其实也很容易理解,参数再多,也就是在栈上,数据类型确定其数据长度的,移动指针即可一依次取出参数。

type va_arg(
   va_list arg_ptr,
   type
);
void va_copy(
   va_list dest,
   va_list src
); // (ISO C99 and later)
void va_end(
   va_list arg_ptr
);
void va_start(
   va_list arg_ptr,
   prev_param
); // (ANSI C89 and later)
void va_start(
   arg_ptr
);  // (deprecated Pre-ANSI C89 standardization version)
  • va_startarg_ptr设置为传递给函数的参数列表中的第一个可选参数。 参数arg_ptr必须具有va_list类型。 参数prev_param是紧跟参数列表中第一个可选参数之前的必需参数的名称。
  • va_argarg_ptr提供的位置中检索类型的值,并通过使用类型的大小来确定下一个参数的开始位置,增量arg_ptr指向列表中的下一个参数。 在函数中,可以使用va_arg任意多次,以从列表中检索参数。
  • va_copy生成其当前状态的自变量列表的副本。 Src参数必须已用va_start初始化;它可能已使用va_arg调用进行了更新,但不得使用va_end重置。 从dest va_arg检索的下一个参数与从src检索到的下一个参数相同。
  • 检索所有参数后, va_end会将指针重置为NULL。 在函数返回之前,必须在va_start或va_copy初始化的每个参数列表上调用va_end 。

简单示例

#include 
#include 

int print(const char * format, ...)
{
	va_list argptr; // char * 指针
	va_start(argptr, format); // 初始化指针,指向不定参数前面的固定参数,即固定参数的最后一个
	const char * args1 = va_arg(argptr, const char *); // 解析参数,移动指针
	va_end(argptr); // 将argptr指针置空
	printf("%s, %s", format, args1);
	return 0;
}

下面示例,计算标准差,主要演示一下使用va_copy的用法

#include 
#include 
#include 

double deviation(int first, ...);

int main( void )
{
    /* Call with 3 integers (-1 is used as terminator). */
    printf("Deviation is: %f\n", deviation(2, 3, 4, -1 ));

    /* Call with 4 integers. */
    printf("Deviation is: %f\n", deviation(5, 7, 9, 11, -1));

    /* Call with just -1 terminator. */
    printf("Deviation is: %f\n", deviation(-1));
}

/* Returns the standard deviation of a variable list of integers. */
double deviation(int first, ...)
{
    int count = 0, i = first;
    double mean = 0.0, sum = 0.0;
    va_list marker;
    va_list copy;

    va_start(marker, first);     /* Initialize variable arguments. */
    va_copy(copy, marker);       /* Copy list for the second pass */
    while (i != -1)
    {
        sum += i;
        count++;
        i = va_arg(marker, int);
    }
    va_end(marker);              /* Reset variable argument list. */
    mean = sum ? (sum / count) : 0.0;

    i = first;                  /* reset to calculate deviation */
    sum = 0.0;
    while (i != -1)
    {
        sum += (i - mean)*(i - mean);
        i = va_arg(copy, int);
    }
    va_end(copy);               /* Reset copy of argument list. */
    return count ? sqrt(sum / count) : 0.0;
}

你可能感兴趣的:(C,不定参数,c)