变量列表参数
说我有2个function
void f1(int p1, int v1, ...);
和
void f2(int v1, ...);
在f1里面我想将所有参数从variadic列表传递给f2:
void f1(int p1, int v1, ...) { f2(/*pass all variadic parameters*/); }
例如,当我调用f1(1, 2, 3, 4, 5)
我想将2,3,4,5传递给f2
它不可能直接使用,但您可以使用va_list
类型来包装完整的值,并将它们传递给采用这种参数的函数版本。 基本上,将f2()
分解为:
void f2v(int v1, va_list args) { // ... // use va_arg() repeatedly to get the various arguments here } void f2(int v1, ...) { va_list args; va_start(args, v1); f2v(v1, args); va_end(args); }
然后重做f1()
以使用f2v()
而不是f2()
:
void f1(int p1, int v1, ...) { // do whatever else you need to do before the call to f2 va_list args; va_start(args, v1); f2v(v1, args); va_end(args); // do whatever else you need to do after the call to f2 }
从理论上讲,这是printf()
和vprintf()
工作方式 – printf()
内部可以调用vprintf()
这样就不需要两个function相同的实现。
(不要忘记 – 你需要#include
才能访问va_list
, va_start()
等)
虽然您已经接受了正确的答案。
如果您无权访问f2
则另一种方法是使用可变参数宏。 这是自C99以来可用的东西:
#define F1(P1, V1, ...) \ do { \ /* do something with P1, V1 */ \ f2(__VA_ARGS__); \ } while(0)
这里do
– while
只是一个封装你的语句的技巧,这样对那个宏的调用可能出现在普通语句的任何地方,并且所有的@都有助于在几行上写宏。
这些宏非常常用于增加printf
以使用前缀打印日志消息,例如:
#define dprintf(...) \ do { \ fprintf(stderr, "%lX: ", (long unsigned)mynum); \ fprintf(stderr, __VA_ARGS__); \ } while(0)
一般来说,你不能这样做。 但是,请看这个问题 。