C语言中的可变参数

一,两种形式的可变参数

第一种的形式的头文件是<varargs.h>

第二种的形式的头文件是<stdarg.h>,是第一种的扩展。

区别:

  • varargs.h比stdarg.h更有移植性,能够运行的系统平台也多一些,且更早。
  • 如果要编写一个遵循ANSIC标准的程序,就必须使用stdarg.h。

二,varargs.h

<varargs.h>中有一些宏包括va_dcl,va_start,va_end以及va_arg。和va_list类型。va_alist一般由编程者来定义。

在函数定义的首部使用va_alist和va_dcl。

varargs.h经典实现

typedef char *va_list;

#define va_dcl  int va_alist

#define va_start(list)   list=(char*)&va_alist

#define va_end(list)

#define va_arg(list,mode)  ((mode*)(list+=sizeof(mode)))[-1] 

varargs.h和stdarg.h中的宏的区别就是va_start,前者只有一个参数就是va_list变量,后者多了一个变量就是最后一个固定参数。其他用法都是一样的。实现也差不多。

二,stdarg.h

stdarg.h这个头文件中包括一组宏和一个类型,此头文件是标准库的一部分。

va_list:可以定义一个变量,用来访问参数列表未确定的部分。其实va_list原型是typedef char* va_list;是一个char* 指针类型。所以这个类型定义出来的变量是存储参数地址的。结合参数类型,就能得出参数值。

va_start(va_list变量,最后一个固定参数):用来初始化va_list定义的变量,使va_list变量指向第一个可变参数。

va_arg(va_list变量,参数类型):返回这个参数的值,并使va_list变量指向下一个可变参数。

va_end(va_list变量):访问最后一个可变参数后,调用此宏。

注意:

底层c语言实现要求函数参数列表在内存中连续存储,只要知道当前参数地址,就能依次访问。

va_arg的第2个参数的类型不能为char ,short,float类型。char和short会转化成int,float会转化成double。


三,可变参数的限制

1,可变参数必须从头到尾逐个访问

2,参数列表中至少有一个确定的命名参数(对于stdarg.h来说)

3,可变参数宏无法知道可变参数的具体数目。需要人为指定

4,可变参数宏无法判断参数的类型。需要认为指定。

四,例子

varargs.h版本的error,printf

#include <stdio.h>
#include <varargs.h>
void error(va_alist) va_dcl
{
    va_list ap;
    char *format;
    va_start(ap);
    format=va_arg(ap,char*);
    vfprintf(stderr,format,ap);
    va_end(ap);
}

int printf(va_alist) va_dcl
{
    va_list ap;
    char* format;
    int n;
    va_start(ap);
    format=va_arg(ap,char*);
    n=vprintf(format,ap);
    va_end(ap);
    return n;

}

stdarg.h版本的error ,printf

#include <stdio.h>
#include <stdarg.h>

void error(char* format,...)
{
    va_list ap;
    va_start(ap,format);
    vfprintf(stderr,format,ap);
    va_end(ap);
}


int printf(char* format,...)
{
    va_list ap;
    int n;
    va_start(ap,format);
    n=vprintf(format,ap);
    va_end(ap);
    return n;
}

利用可变参数求和

#include <stdio.h>
#include <stdarg.h>

int sum(int values,...)
{
    va_list ap;
    va_start(ap,values);
    int sum=0;
    int i=0;
    for(i=0;i<values;i++)
    {
        sum+=va_arg(ap,int)
    }
    va_end(ap);
    return sum;
}

猜你喜欢

转载自blog.csdn.net/qq_33436509/article/details/82081680