2010-04-13 59 views
18

如果我定義了一些宏:循環通過宏觀可變參數值

#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

回答

21

不,我能想到的...

不過,如果你對這個應用程序正在處理可變數量的相同類型的參數,如:

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