我正在查看老师给我的代码,我发现了这个:
#define setBit(var, bitnum) (var)|=(1<<(bitnum))
#define resBit(var, bitnum) (var)&=~(1<<(bitnum))
#define ROW_RESET setBit(PORTA,4) ; resBit(PORTA,4)
前两个#define
语句是自解释的,但我对第三个问题有所了解。第三个陈述(行)是对的吗?我们可以用分号(;)后写语句,如果是,那么请你解释一下这里发生了什么。
答案 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连接到在上升沿触发的内容,并且可以处理小于处理器时钟速率的脉冲。