循环通过宏观可变参数值

问题描述:

如果我定义了一些宏:循环通过宏观可变参数值

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

是否有某种方式来实际遍历args,而不是把它传递给另一个函数?喜欢的东西

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

可能重复[?是否可以遍历在复杂的宏参数(HTTP://计算器和问题可以一些预处理魔术来解决.com/questions/1872220/is-it-it-it-it-ite-over-arguments-in-variadic-macros) – 2015-09-18 10:44:35

不,我能想到的...

不过,如果你对这个应用程序正在处理可变数量的相同类型的参数,如:

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

你不介意使用一个函数来帮助,那么有一些有用的技巧可以完成。

这里的主要问题是你不能直接将这些参数传递给可变参数函数,因为没有办法让该函数知道有多少参数需要读取。

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

#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 
$ 
+1

一个肯定全面的答案,谢谢。但我想我会避免使用这种方法:) – 2010-04-14 17:22:47

+0

我喜欢预处理器,它只是非常不错 – RichardBruce 2013-12-24 02:44:57