C/C++実現可変パラメータ


引用する
C言語は可変パラメータ,すなわちパラメータ個数が固定されず,printf,scanfなどの典型的な関数は数不定のパラメータを受け入れることができる.
例えばprintf(「one parameter」);printf("two parameter: %d", a);printf("three parameter: %d, %s", a, s);
上の3つのprintfはそれぞれ1,2,3つのパラメータを受信する.printfのプロトタイプを見てみましょう.
#include
int printf(const char *format, ...);
このことからprintfは固定パラメータformatを受信する以外は,後のパラメータは「...」を用いることが分かる.ことになる0個以上のパラメータが受け入れられることを示します.
1つのタイプの3つのマクロ
void va_start(va_list ap, last);
type va_arg(va_list ap, type);
void va_end(va_list ap);
va_Listタイプのほとんどの場合char*、すなわちtypedef char*va_list;
va_startは2つのパラメータを受信し、1つはva_listタイプの変数で、1つは省略記号の前の最後の名前のあるパラメータで、このマクロは実際に初期化されています.
va_argは2つのパラメータを受信し、1つは初期化後のva_である.list変数は、返されるパラメータタイプであり、呼び出されるたびに次のパラメータが返されます.
va_end受信va_list変数、クリーンアップ作業を行います.
可変パラメータ関数を実現するのは簡単で、3ステップで行けます:va_start初期化、va_argパラメータ、va_end現場を片付ける.

次のプログラムは2つの可変パラメータ関数を実現し、maxIntはn個の整数を受け入れ、最大の数を返す.maxStrはn文字列を受け入れ、最も長い文字列を返します.
#include <stdarg.h>
#include <iostream>
using namespace std;

int maxInt(int num, ...);
std::string maxStr(int num, ...);

int main()
{
    int n = maxInt ( 5, 5, 6 ,3 ,8 ,5);
    cout << n;
    std::string m = maxStr(5, "a", "ab", "abc", "abcd", "abcde");
    std::cout << m << std::endl;
    return 0;
}

int maxInt(int num, ...)
{
    int m = 0;
    va_list ap;
    va_start(ap, num);
    for ( int i= 0; i< num; i++ )
    {
        int t = va_arg (ap, int);
        if ( t > m )
        {
            m = t;
        }
    }
    va_end (ap);
    return m;
}


std::string maxStr(int num, ...)
{
    std::string ret;
    va_list ap;
    va_start(ap, num);
    for(int i = 0; i < num; i++)
    {
        std::string l_tmp = va_arg(ap, char*);
        std::cout << "get param: " << l_tmp << std::endl;
        if(l_tmp.length() > ret.length()) ret = l_tmp;
    }
    va_end(ap);
    return ret;
}

その他
1.可変パラメータ関数には固定パラメータが必要ですか?
必ずしもそうではありませんが、環境によってはva_startはva_を1つしか受信しませんlistタイプパラメータです.この場合、可変パラメータ関数にはパラメータがなくても検証されていない可能性があります.
2.va_についてcopy
va_copyプロトタイプはvoid va_copy(va_list dest, va_list src);2つのvaが提供されています.Listコピー機能.標準Cではなく、C 99で定義されているので、選択して使用できます.