我想要实现类似这样的效果:
#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(x) {PORTB=0,PORTC=0,PORTD=0}
MACRO(0); //This would get replaced by PORTB=0;
MACRO(1); //PORTC=0;
MACRO(2); //PORTD=0;
可以使用预处理器进行操作,但这样做可能会被认为很丑陋。
#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)
MACRO(0)
的预处理器输出为(((0) == 0) ? B=0 : ((0) == 1) ? C=0 : D=0) ;
。 - Jabberwocky
if (i >= 0 && i <= 2) MACRO(i);
或类似的东西。如果它是微控制器,我怀疑您不想要那样做,但我认为MACRO(1);
比代码中的PORTC=0;
更清晰 — 实际上,对我来说它不太清晰。但这在某种程度上可能是问题的产物。如果宏背后的代码选择了 PORTB、PORTC 或 PORTD 中的一个用于赋值语句的左侧(因此使用方式为MACRO(1) = 0
),那么我的建议将不起作用 — 正如我在“不扩展或概括”注释中所指出的那样。 - Jonathan Lefflerswitch
的内联函数将完美地完成任务,并且优化编译器将能够生成相同的代码,如果参数是编译时常量。 - 5gon12eder