可変パラメータリストの使用方法の概要


私たちが関数を使用するとき、一般的には中のパラメータが与えられていることが多く、私たちが一般的に使用するときは3つのパラメータを超えませんが、これは3つ以上のパラメータが現れないことを排除していません.例えば、平均値を求めたり、和を求めたり、3つ以上のパラメータが現れる可能性がある関数演算を排除していません.このとき、私たちのパラメータは固定されていません.いつでも変化していくのですしたがって,それらを実現する方法が必要であり,この方法はC言語が我々に提供した可変パラメータリストと呼ばれる関数法である.
まず、可変パラメータのリストはマクロによって定義され、これらのマクロはのヘッダファイルにあるので、使用時にヘッダファイルを参照し、参照後に次の3つのマクロの関数が必要です.
void va_start(va_list ap, last);
type va_arg(va_list ap, type);
void va_end(va_list ap);

上記の3つの関数はマクロで定義されています.次に、これらのマクロの標準ANSI形式での定義を示します.
typedef char * va_list;
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end(ap) ( ap = (va_list)0 )

上のマクロから、
va_Listは実際には文字タイプのポインタです.
_INTSIZOF()という関数は,主に伝達されたnの長さをintの長さの整数倍にする.
va_startの主な役割はva_List定義のポインタはvの後ろを指す,すなわち可変パラメータの最初の数のヘッダアドレスであり,実際にはva_listを初期化します.
va_argは現在のパラメータを取り出しva_listで定義されたポインタ変数は次のパラメータを指し、tはパラメータタイプを指す.
va_endは、パラメータリスト全体をクリーンアップするか、解放すると理解される.
以下は1つの簡単な例を通じて具体的な実現方法を見ます---可変パラメータリストを通じて複数の数の最大値を求めることを実現します
#include<stdarg.h>
int MAX(int count,...)
{
    int i=0;
    int max=0;
    int k=0;
    va_list arg;   //    va_list     
    va_start(arg,count);  // arg  count         ,     
    max=va_arg(arg,int);  //          ,          
    for(i=0;i<count-1;i++)
    {
      k=va_arg(arg,int);  //  count    
      if(k>max)          //    
      max=k;
    }
    va_end(arg);   //      
    return max;
}

これがCにおける可変パラメータの使い方であり,我々のprintf,scanfなどはそれらによって実現されているが,もちろん可変パラメータリストは複数のパラメータを受け入れることができるが,少なくとも1つのパラメータが必要であることに注意しなければならない.