#define语句解释

时间:2015-03-09 18:51:57

标签: c c-preprocessor

我正在查看老师给我的代码,我发现了这个:

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

前两个#define语句是自解释的,但我对第三个问题有所了解。第三个陈述(行)是对的吗?我们可以用分号(;)后写语句,如果是,那么请你解释一下这里发生了什么。

2 个答案:

答案 0 :(得分:6)

分号可用于宏定义,只会使宏扩展为多个语句:

ROW_RESET;

将扩展为

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

也允许使用例如在宏定义中使用大括号的块语句,只要扩展后的结果在语法上有效(在扩展时)。

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

答案 1 :(得分:0)

一位经验丰富的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,然后将相同的位设置为零。这可能是一个类似于Atmel芯片的嵌入式系统,该地址处的某些存储器映射I / O连接到在上升沿触发的内容,并且可以处理小于处理器时钟速率的脉冲。