#define中的数组

时间:2014-09-24 14:20:09

标签: c c-preprocessor

我正在努力实现这样的目标:

#define MACRO(x) {PORTB=0,PORTC=0,PORTD=0}

MACRO(0); //This would get replaced by PORTB=0;
MACRO(1); //PORTC=0;
MACRO(2); //PORTD=0;

我想创建一个“宏数组”。我会传入一个索引,它会返回正确的代码。

这可能吗?

修改

如果有帮助,PORTB,PORTC和PORTD都是#defines。

2 个答案:

答案 0 :(得分:5)

可以使用预处理器完成,但它可以说是丑陋的。

#define MACRO_CASE0 PORTB = 0
#define MACRO_CASE1 PORTC = 0
#define MACRO_CASE2 PORTD = 0

#define MACRO(X) MACRO_CASE##X

另请查看Boost.Preprocessor库。 (它适用于C和C ++。)

更新:在与Jonathan Leffler讨论之后(见下文),我觉得有义务更新答案,劝告新C程序员不要滥用(强大但肮脏)技术如上所示。

如果您 - 正如OP请求的那样 - 希望传入一个索引并且它将返回正确的代码,那么您需要采用预处理器编程。但是,如果你想要做的只是基于某些条件执行不同的代码,并且如果条件是编译时常量,那么希望它没有运行时开销,那么以下方法不仅仅是更清洁,但也更灵活,因为它也允许传递运行时值。

/* '#include' this definition in any file where you want to use it. */
static inline void
do_the_right_thing(const int selector)
{
  switch (selector)
    {
   case 0:
      PORTB = 0;
      break;
   case 1:
      PORTC = 0;
      break;
   case 2:
      PORTD = 0;
      break;
   default:
      assert(!"cannot do the right thing: invalid selector");
    }
}

现在,在您的代码中,如果您编写

do_the_right_thing(1);  /* selector is a compile-time constant */
与使用宏相比,启用适当优化的合适编译器不会产生任何开销。但是,您也可以写

do_the_right_thing(rand() % 3);  /* selector is a run-time expression */

并且编译器将插入一些快速切换代码以在运行时选择适当的操作。

答案 1 :(得分:3)

这可以完成任务,但它不会非常优雅地扩展或概括:

#define MACRO(x) (((x) == 0) ? PORTB=0 : ((x) == 1) ? PORTC=0 : PORTD=0)