通过宏观可变参数值循环 [英] Looping through macro Varargs values

查看:77
本文介绍了通过宏观可变参数值循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我定义了一些宏:

 的#define富(参数...)({/ *做某事* /})

有没有一些方法来真正遍历 ARGS ,而不是把它传递给另一个函数?类似

 的#define富(参数...)\\
        {\\
           的for(int i = 0; I<的sizeof(参数); ++ I){\\
             / *做一些ARGS [I] * / \\
           } \\
         }


解决方案

不,我能想到的...

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

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

和你不介意使用功能来帮助,那么就可以做一些有用的挂羊头卖狗肉。

这里的主要问题是,你不能仅仅通过这些参数直接到一个可变参数的函数,因为没有办法为函数知道有多少个参数阅读。而这个问题的可以的用一些preprocessor魔法解决:

 的#include<&stdio.h中GT;
#包括LT&;&STDARG.H GT;#如果定义(__ STDC_VERSION__)及和放大器; (__STDC_VERSION__> = 199901L)/ * C99风格:由__VA_ARGS__引用匿名说法,空ARG也不行* /#定义N_ARGS(...)N_ARGS_HELPER1(__ VA_ARGS__,9,8,7,6,5,4,3,2,1,0)
#定义N_ARGS_HELPER1(...)N_ARGS_HELPER2(__ VA_ARGS__)
#定义N_ARGS_HELPER2(X1,X2,X3,X4,X5,X6,X7,X8,X9,正,...)n表示#定义富(...)foo_helper(N_ARGS(__ VA_ARGS__),__VA_ARGS__)#elif指令定义(__ GNUC__)/ * GCC风格:命名的参数,空arg是OK * /#定义N_ARGS(参数...)N_ARGS_HELPER1(参数,9,8,7,6,5,4,3,2,1)
#定义N_ARGS_HELPER1(参数...)N_ARGS_HELPER2(参数)
#定义N_ARGS_HELPER2(X1,X2,X3,X4,X5,X6,X7,X8,X9,正,X ...)n表示#foo定义(参数...)foo_helper(N_ARGS(参数)参数)#其他你的编译器#ERROR复杂的宏在这里#万一静态内嵌无效foo_helper(unsigned int类型n_args,...)
{
  无符号整型我,ARG;
  va_list的AP;  的va_start(AP,n_args);
  的printf(%U参数(S):\\ n,n_args);
  对于(i = 0; I< n_args;我++){
    ARG =在va_arg(AP,无符号整型);
    的printf(%U \\ N,ARG);
  }
  va_end用来(AP);
}INT主要(无效)
{
  富(0);
  富(10,20,30);
  富(1,2,3,4,5,6,7,8,9);
  返回0;
}

输出:

  $ GCC -W -Wall -std = C99 -pedantic -o va_macro va_macro.c
$ ./va_macro
1参数(S):
  0
3参数(S):
  10
  20
  三十
9参数(S):
  1
  2
  3
  4
  五
  6
  7
  8
  9
$

If I define some macro:

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

Is there some way to actually loop through args rather than pass it along to another function? Something like

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

解决方案

Not that I can think of...

However, if your application for this is handling a variable number of arguments of the same type, e.g.:

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

and you don't mind using a function to help, then there is some useful trickery that can be done.

The main problem here is that you can't just pass these arguments straight to a varargs function, because there's no way for that function to know how many arguments there are to read. And that problem can be solved with some preprocessor magic:

#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;
}

Output:

$ 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
$ 

这篇关于通过宏观可变参数值循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆