#define语句解释

#define statement explanation

我正在研究我老师给我的代码,我遇到了这个:

#define setBit(var, bitnum)   (var)|=(1<<(bitnum))
#define resBit(var, bitnum)   (var)&=~(1<<(bitnum))
#define ROW_RESET       setBit(PORTA,4) ; resBit(PORTA,4)

前两个 #define 语句是不言自明的,但我在理解第三个时遇到了问题。第三个说法(行)对吗?我们可以在分号(;)之后写语句吗,如果可以,请你解释一下这里发生了什么。

可以在宏定义中使用分号,并且只会使宏扩展为多个语句:

ROW_RESET;

将扩展到

setBit(PORTA,4) ; resBit(PORTA,4);

也可以使用例如宏定义中带有花括号的块语句,只要扩展后的结果在语法上有效(在扩展的地方)。

像往常一样,您在宏中做的事情 "fancy" 越多,就越容易出错 - 例如,如果您有一个带有签名 void foo(int) 的函数,您可以调用 foo(setBit(PORTA, 4)),但 foo(ROW_RESET) 不会编译,因为它会扩展为 foo(setBit(PORTA,4) ; resBit(PORTA,4))(这是非法的,因为函数调用中不能有分号)。

更有经验的 C 程序员会这样写:

#define setBit(var, bitnum)   ((var)|=(1<<(bitnum)))
#define resBit(var, bitnum)   ((var)&=~(1<<(bitnum)))
#define ROW_RESET do { setBit(PORTA,4); resBit(PORTA,4); } while (0)

...然后,我会去检查 PORTA 是否被定义为一个简单的常量,而不是一些可能有副作用的表达式。

至于宏的作用,它非常简单:将某个位设置为 1,然后将同一位设置为 0。这可能是一个嵌入式系统,如 Atmel 芯片,在该地址处有一些内存映射 I/O 连接到在上升沿触发的东西,并且可以处理小于处理器时钟速率的脉冲。