3

初めての作業va_listなので、自分が何をしているのかよくわかりません。さて、基本的に私が持っているのは、順序付けられた関数の数字の束(1、2、3、4、5)であり、それらを印刷してもらいます。これは正常に機能します。

#include <iostream>
#include <cstdarg>

using namespace std;

void ordered(int num1, double list ...);

void main()
{ 
    ordered(5, 1.0, 2.0, 3.0, 4.0, 5.0);
}

void ordered(int num1, double list ...)
{
    va_list arguments;

    va_start(arguments, num1);

    list = va_arg(arguments, double);
    cout << "There are " << num1 << " numbers" << endl;

    do { 
        cout << list << endl; // prints out 1 then 2 then 3 then 4 then 5
        list = va_arg(arguments, double);
    } while (list != 0);

    // at this point, list = 0

    va_end(arguments);
}

問題は、そのva_end(arguments);前後に、プログラムにリストをもう一度印刷させたいということです。基本的に、別の機能を作成せずに、1、2、3、4、5をもう一度印刷します。コードを複製しようとしました:

va_start(arguments, num1);

do { 
    cout << list << endl;
    list = va_arg(arguments, double);
} while (list != 0);

va_end(arguments);

成功せずに。listプログラムをもう一度繰り返すにはどうすればよいですか、それとも同じ機能でもう一度繰り返すことはできませんか?

4

3 に答える 3

5

実用的な実装は次のとおりです。

#include <iostream>
#include <cstdarg>

using namespace std;

void ordered(int num1, ...); // notice changed signature


int main(int,char**)
{ 
    ordered(5, 1.0, 2.0, 3.0, 4.0, 5.0);
    return 0;
}

void ordered(int count, ...) // notice changed signature
{
    va_list arguments;

    va_start(arguments, count);

    cout << "There are " << count << " numbers" << endl;

    double value = 0.0;

    // notice how the loop changed
    for(int i = 0; i < count; ++i) { 
        value = va_arg(arguments, double); 
        cout << value << endl; // prints out 1 then 2 then 3 then 4 then 5
    } 

    // at this point, list = 0

    va_end(arguments);

    va_list arg2;
    va_start(arg2, count);

    cout << "There are " << count << " numbers" << endl;

    for(int i = 0; i < count; ++i) { 
        value = va_arg(arg2, double);
        cout << value << endl; // prints out 1 then 2 then 3 then 4 then 5
    } 

    // at this point, list = 0

    va_end(arg2);

}
于 2013-03-27T13:30:22.597 に答える
3

マニュアルページから:

va_end()

の各呼び出しは、同じ関数内のva_start() 対応するの呼び出しと一致する必要があります。va_end()呼び出し後va_end(ap)変数apは未定義です。

リストの複数のトラバーサル。それぞれがとで囲まれva_start()va_end()いる可能性があります。

それを試したがうまくいかなかったコードを見せてもらえますか?

NB。も参照してください。これを使用して、 (破壊的に)トラバースする前にva_copy複製を作成し、複製をトラバースすることもできます。arguments

于 2013-03-27T13:28:24.493 に答える
1

簡単な答え(varargsが実際にどのように機能するかを無視すると、の外で有効なユースケースを見つけるのは難しいと思いますprintf)は、引数を自分でコピーすることです。ええと、実際にはもっと簡単な答えはvarargsをまったく使用しないことです...なぜコンテナを渡さないのですか(またはC ++ 11では?を使用しinitializer_listますか?)

于 2013-03-27T13:34:39.087 に答える