循环通过宏Varargs值

如果我定义一些宏:

#define foo(args...) ({/*do something*/}) 

有没有办法实际循环args而不是传递给另一个函数? 就像是

 #define foo(args...) \ { \ for (int i = 0; i < sizeof(args); ++i) { \ /*do something with args[i]*/ \ } \ } 

不是我能想到的……

但是,如果您的应用程序正在处理相同类型的可变数量的参数,例如:

 foo(0); foo(10, 20, 30); foo(1, 2, 3, 4, 5, 6, 7, 8, 9); 

并且你不介意使用函数来帮助,那么可以做一些有用的技巧。

这里的主要问题是你不能直接将这些参数传递给varargs函数,因为该函数无法知道有多少参数需要读取。 这个问题可以通过一些预处理器魔术来解决:

 #include  #include  #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99-style: anonymous argument referenced by __VA_ARGS__, empty arg not OK */ # define N_ARGS(...) N_ARGS_HELPER1(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) # define N_ARGS_HELPER1(...) N_ARGS_HELPER2(__VA_ARGS__) # define N_ARGS_HELPER2(x1, x2, x3, x4, x5, x6, x7, x8, x9, n, ...) n # define foo(...) foo_helper(N_ARGS(__VA_ARGS__), __VA_ARGS__) #elif defined(__GNUC__) /* GCC-style: named argument, empty arg is OK */ # define N_ARGS(args...) N_ARGS_HELPER1(args, 9, 8, 7, 6, 5, 4, 3, 2, 1) # define N_ARGS_HELPER1(args...) N_ARGS_HELPER2(args) # define N_ARGS_HELPER2(x1, x2, x3, x4, x5, x6, x7, x8, x9, n, x...) n # define foo(args...) foo_helper(N_ARGS(args), args) #else #error variadic macros for your compiler here #endif static inline void foo_helper(unsigned int n_args, ...) { unsigned int i, arg; va_list ap; va_start(ap, n_args); printf("%u argument(s):\n", n_args); for (i = 0; i < n_args; i++) { arg = va_arg(ap, unsigned int); printf(" %u\n", arg); } va_end(ap); } int main(void) { foo(0); foo(10, 20, 30); foo(1, 2, 3, 4, 5, 6, 7, 8, 9); return 0; } 

输出:

 $ gcc -W -Wall -std=c99 -pedantic -o va_macro va_macro.c $ ./va_macro 1 argument(s): 0 3 argument(s): 10 20 30 9 argument(s): 1 2 3 4 5 6 7 8 9 $