c - #define 中的数组

标签 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。

最佳答案

可以使用预处理器来完成,但可以说它很丑。

#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 */

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

关于c - #define 中的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26019303/

相关文章:

C编程: error: expected ‘)’ before string constant

c++ - MinGW 中预处理器 g++ 的奇怪行为

c - 使用优化的内存带宽方法时,我没有看到性能提升

c - 在 C 中使用 SHA1

C宏定义可以引用其他宏吗?

c - 一种在函数调用中定义新变量的方法

c++ - 我如何#include 一个名称由宏构建的文件?

c++ - Scons - 使用带有 scons 缓存的自定义预处理器

c - 轮盘赌选择的实现

c - SEEK_HOLE 始终指向文件末尾