简体   繁体   English

传递va_list的一部分

[英]Passing part of a va_list

How would I pass part of a va_list or copy part into another va_list starting at the nth element? 我将如何传递va_list的一部分或将其复制到从第n个元素开始的另一个va_list中?

int main (int x, char**argv) {
    va_list clientArgs;
    va_copy(clientArgs, argv[3]); // get all input parameters after 3rd cmd line arg

    foo(clientArgs);

    va_end(clientArgs);
    ....

Or using the va_copy method ... ? 还是使用va_copy方法...?

Any code will not be portable, or even guaranteed to work (undefined behavior and all that) 任何代码都不是可移植的,甚至不能保证正常工作(未定义的行为等)

However, it is possible, as the code below demonstrates: 但是,如下面的代码所示,这是可能的:

#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <stdarg.h>

void VarShowArgs(int n, va_list args)
{
    for(int i=0; i<n; ++i)
    {
        printf("Arg #%d: %d\n", i+1, va_arg(args, int));
    }
}

void ShowArgs_StartAtFourthParam(int n, ...)
{
    va_list args;
    int dummy;

    va_start(args,n);          // n is param #1 (value = 8)
    dummy = va_arg(args, int); // Remove Param #2 from args (value = 1)
    dummy = va_arg(args, int); // Remove Param #3 from args (value = 2)

    // Show arguments starting at Param #4 (which should be value = 3)
    VarShowArgs(n - 2, args);  // Minus 2 because we removed 2 params from the args.

    va_end(args);
}


int main(void)
{
    // First param says how many more args there will be.
    // This function shows the values starting at the 4th argument (value = 3)
    ShowArgs_StartAtFourthParam(8, 1, 2, 3, 4, 5, 6, 7, 8);
    getch();
    return 0;
}

Output 产量

Arg #1: 3
Arg #2: 4
Arg #3: 5
Arg #4: 6
Arg #5: 7
Arg #6: 8

What do you mean "part of a va_list"? 您是什么意思“ va_list的一部分”? The question doesn't really make a lot of sense. 这个问题并没有多大意义。

A va_list is an iterator object that allows you to iterate through the arguments to a function one at a time -- va_start initializes it to point to the argument after a specific argument of the current function, while va_arg gets (copies) the currently pointed at argument and increments it to point at the next argument. va_list是一个迭代器对象,它允许您一次遍历一个函数的参数va_start将其初始化为指向当前函数的特定参数之后的参数,而va_arg获取(复制)当前指向的参数参数并将其递增以指向下一个参数。

In no case does the va_list encapsulate the argument list -- its just an abstract pointer-like object that refers to the argument list. va_list在任何情况下都不会封装参数列表-它只是引用参数列表的抽象指针式对象。

You can pass a pointer to the va_list object to some other function and have that function call va_arg to process some of the arguments. 您可以将指向va_list对象的指针传递给其他函数,并使该函数调用va_arg来处理某些参数。 After it returns, you can then call va_arg to process more arguments, but this isn't making a copy of the argument list in any real sense. 返回后,您可以调用va_arg来处理更多参数,但这并没有真正复制参数列表。

You can use va_copy to copy a va_list in order to have TWO iterators going through the argument list. 您可以使用va_copy复制va_list ,以使两个迭代器遍历参数列表。 Each is then independent, so each will see all the arguments after the point at which the va_copy was done. 然后,每个参数都是独立的,因此每个参数都将在va_copy完成后看到所有参数。

There's no way to create a va_list object that refers to anything other than the arguments passed to the current function as ... 除了引用作为参数传递给当前函数的参数外,无法创建引用任何其他内容的va_list对象...

You can't do it directly. 您不能直接这样做。 The second argument to va_start should be the name of the last parameter before the ellipsis (...) in the function's argument list. va_start的第二个参数应该是函数参数列表中省略号(...)之前的最后一个参数的名称。 Using anything else leads to undefined behaviour at best. 使用其他任何东西最多只能导致未定义的行为。

To be able to approximate what you're after, you have to know what the values are at the front of the va_list . 为了能够大致了解所需内容,您必须知道va_list You can use va_arg() to read them, and then pass what's left of the va_list to your other function: 您可以使用va_arg()读取它们,然后将va_list的剩余内容传递给其他函数:

void function(int arg1, char *arg2, ...)
{
    va_list args;
    va_start(args, arg2);
    int i = va_arg(args, int);
    double d = va_arg(args, double);
    foo(args);
    va_end(args);
}

Clearly, if the arguments in the variable list are all the same type, you can use a loop to iterate over the first N such arguments. 显然,如果变量列表中的参数都是相同的类型,则可以使用循环来迭代前N个此类参数。 Note that there is no way to find out how many arguments were provided; 注意,没有办法找出提供了多少个参数。 your code must 'know'. 您的代码必须“知道”。 For example, printf() uses the format string to tell it how many arguments were provided (and the type of each argument). 例如, printf()使用格式字符串告诉它提供了多少个参数(以及每个参数的类型)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM