va_list和va_arg

问题描述 投票:4回答:3

我这样使用va_list:

void foo(const char* firstArg, ...) {
    va_list args;
    va_start (args, firstArg);
    for (const char* arg = firstArg; arg != NULL; arg = va_arg(arg, const char*)) {
         // do something with arg
    }

    va_end(args);
}

foo(“ 123”,“ 234”,“ 345”)

前三个参数正确地传递给foo,但是在完成“ 345”的位置,

 arg = va_arg(arg, const char*) 

将其他一些怪胎值设置为arg

所以有什么问题。我使用llvm3.0作为编译器。

c variadic-functions
3个回答
11
投票

C不会自动将NULL放在...参数列表的末尾。如果要使用NULL检测参数的结尾,则必须显式传递它。某些函数(例如printf)使用较早的参数来确定何时到达参数末尾。

Edit:实际上,如果您想将NULL放在末尾,则需要将其强制转换为适当的类型,以便将其作为空指针的正确类型传递。)


4
投票

我认为循环应该如下:

for (const char* arg = firstArg; arg != NULL; arg = va_arg(args, const char*))

更改为va_arg(args, const char*)而不是va_arg(arg/*<<==*/, const char*)


0
投票

我使用以下方法实现它。

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

void foo_func
  (char* first, ...)
{
  va_list args;
  va_start(args, first);
  for
    (char* arg = first;
    arg != NULL;
    arg = va_arg(args, char*))
  {
    printf("%s", arg); // or whatever else you want
  }

    va_end(args);
}

#define foo(...) foo_func(__VA_ARGS__, NULL)

int main()
{
  foo("123", "234", "345"); // outputs: 123234345
}

预处理器在每个调用的末尾放置一个NULL,因此您的代码看起来更干净。


这个答案我迟到了8年。希望对其他人有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.