2

以下のコードには、指定された整数値のリストの合計を計算する 2 つの関数が含まれています。

#include <iostream>
#include <stdarg.h>

using namespace std;

int sum_1 ( int number_of_values, ... )
{
    va_list arguments;
    va_start ( arguments, number_of_values );
    int sum = 0;
    for ( int i = 0; i < number_of_values; i++ )
    {
        sum += va_arg ( arguments, int );
    }
    va_end ( arguments );

    return sum;
}

int sum_2 ( int number_of_values ...)
{
    int sum = 0;
    for ( int i = 0; i < number_of_values; i++ )
        sum += *( &number_of_values + i + 1 );
    return sum;
}


int main()
{
    cout << sum_1(3, 1, 2, 3) << endl; //prints 6
    cout << sum_2(3, 1, 2, 3) << endl; //prints 6
}

sum_1va_listアプローチを使用sum_2し、提供された変数のアドレスを使用して、number_of_values他の値を見つけてそれらを加算します。

では、これら2つのアプローチの違いは何ですか? どちらを使用しますか?2 番目のほうが短く見えるのでva_list、 、va_startva_artおよびを定義するのに何を注意しましたva_endか?

4

2 に答える 2

3

2 番目のバージョンは移植性がなく、これは最初のバージョンを使用するための強力な議論です。

2 番目のバージョンは、プラットフォーム上で関数の引数が特定の方法でスタックに配置されている場合にのみ機能します。varargs を使用すると、それが抽象化されます。これにより、最初のバージョンが移植可能になります。

于 2013-08-20T13:45:22.517 に答える
2

2 番目のアプローチでは、引数が関数に渡される方法について仮定を行います。これらの仮定が満たされる必要はありません。va_listライブラリ ベンダーは、引数がどのように渡されるかを知っており、コードを正しく実装できます。

于 2013-08-20T13:57:05.670 に答える