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()

您能否显示您尝试过但不起作用的代码?

注意。另请参阅va_copy,您可以使用它复制arguments之前(破坏性地)遍历它,然后也遍历副本。

于 2013-03-27T13:28:24.493 回答
1

简单的答案(忽略 varargs 的实际工作原理,我发现很难在 之外找到有效的用例printf)是自己复制参数。好吧,实际上更简单的答案是根本不使用可变参数...为什么不传递容器(或者在 C++11 中使用initializer_list?)

于 2013-03-27T13:34:39.087 回答