我想实现这样的事情:阵列中的#define
#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都是#define语句。
我想实现这样的事情:阵列中的#define
#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都是#define语句。
它可以通过预处理器来完成,但它可以说是丑陋的。
#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 */
,编译器会插入一些快速切换代码选择在运行时适当的操作。
这将做任务,但它并没有延长或概括很优雅:
#define MACRO(x) (((x) == 0) ? PORTB=0 : ((x) == 1) ? PORTC=0 : PORTD=0)
...并且效率不高(OP代码看起来像某些微控制器的代码)。 – 2014-09-24 14:25:19
@MichaelWalz:什么是低效?这是问题中显示的示例的编译时常量。首先这不是一个好主意,但它确实按照要求做了什么。 – 2014-09-24 14:26:43
实际上,它**效率很高,因为编译器会优化所有内容。宏MACRO(0)的预处理器输出是(((0)== 0)?B = 0:((0)== 1)?C = 0:D = 0);' – 2014-09-24 14:40:14
+1:与我的[答](http://stackoverflow.com/a/26019383/15168)相比,这有一个优点,它只能用于整数常量的参数;它也有缺点。 – 2014-09-24 14:32:29
@JonathanLeffler真的,但谁会想用一个整数索引一个数组?如果你想,你也可以使用符号名称。 – 5gon12eder 2014-09-24 14:34:43
这取决于你是否想要动态选择索引:'if(i> = 0 && i <= 2)MACRO(i);'或者类似的东西。如果它是一个微控制器,我怀疑你不想要那个,但是在代码中我看不到'MACRO(1);'比'PORTC = 0'更清晰 - 实际上它少了很多对我清楚。但是,这可能部分地成为问题的假象。如果宏背后的代码是选择PORTB,PORTC或PORTD中的一个用于赋值的LHS(因此用法是“MACRO(1)= 0”),那么我建议不起作用 - 正如我的'不扩展或概括'评论。 – 2014-09-24 14:41:38