如何在C函数中使用__VA_ARGS__而不是宏?


How to use __VA_ARGS__ inside a C function instead of macro?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
C/C++: Passing variable number of arguments around

我目前正在使用我的C文件中声明的以下宏。

1
#define COMMON_Print(...) printf (__VA_ARGS__)

现在该调用工作得很好,但事实证明我需要能够创建一个看起来像这样的C函数:

1
2
3
4
void COMMON_Print(...)
{    
    printf (__VA_ARGS__);
}

因此该功能不起作用,我收到错误

"Error : undefined identifier __VA_ARGS__"

我的项目的复杂性需要有一个函数,因为它是一个接口......那么如何获取参数...并将它们传递给printf函数? 或者更好的是我做错了什么?

谢谢!


每个?printf函数都有一个相应的v?printf函数,它执行相同的操作,但是接受一个va_list,一个可变参数列表。

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <stdarg.h>

void COMMON_Print(char *format, ...)
{
    va_list args;

    va_start(args, format);
    vprintf(format, args);
    va_end(args);
}

附注:请注意,va_start...之前的最后一个参数的名称作为参数。 va_start是一个宏,它执行一些基于堆栈的魔法来检索变量参数,它需要最后一个固定参数的地址才能执行此操作。

因此,必须至少有一个固定参数,以便将其传递给va_start。这就是我添加format参数而不是坚持使用更简单的COMMON_Print(...)声明的原因。

请参阅:http://www.cplusplus.com/reference/clibrary/cstdio/vprintf/


__VA_ARGS__仅适用于宏;可变函数是相当不同的。您需要使用stdarg.h中的va_startva_argva_end来处理它们。

首先,您的函数至少需要一个命名参数,例如:

1
void COMMON_Print(const char* fmt, ...)

然后你可以定义一个va_list并使用va_start来设置它:

1
2
3
4
va_list args;
va_start(args, fmt);
// your code here
va_end(args);

现在您可以使用args来访问参数;调用va_arg(args, TYPE)将返回下一个可变参数,所以你可以继续调用它,直到你读完所有的参数。

如果您只是尝试调用printf,则会有一个名为vprintf的printf变体直接接受va_list

1
vprintf(fmt, args);

没有简单的方法可以从另一个函数中调用一个可变函数;你需要像vprintf那样的整个va_list


__VA_ARGS__仅适用于宏。

将变量数量的参数链接到另一个函数不能直接完成。相反,你必须
传递一个va_list,你正在调用的函数必须带一个va_list。幸运的是有一个printf的变体,这样做,你的功能必须这样写:

1
2
3
4
5
6
7
void COMMON_Print(char *format,...)
{    
  va_list args;
  va_begin(args,format);
  vsprintf(format,args);
  va_end(args);
}


您正在寻找的是省略号算子。