在定义预处理器语句中使用括号
所以我想知道什么时候使用
#define xxx (yyy)
VS
#define xxx yyy
我的项目包含一个在AD0_ADMD_CT上有自己定义的文件,如果我想重新定义它们,我需要在定义中使用(AD0_ADMD_CT)或AD0_ADMD_CT吗?
AD0_ADMD_CT定义为
#define AD1_ADMD_CT (IO_AD1.ADMD.bit.CT)
所以它也是
#define AD0_COMPARETIME (AD0_ADMD_CT)
要么
#define AD0_COMPARETIME AD0_ADMD_CT
两者都没有区别。 在第一种情况下, XXX
被yyy
取代,而(yyy)
则是第二种情况。 使用包围的惯例是避免可能发生的逻辑错误。 例如,您将添加function定义为:
#define f(N) N+N int a = f(5)*f(5)
预期值为10 * 10 = 100,但输出为35,因为在编译时变为
int a = 5+5*5+5,
因此使用运算符首选项规则,输出更改。
所以括号避免了这些类型的错误。
通过添加括号,您强制在括号内的参数在宏体的其余部分之前进行求值,所以如果你有
#define MULT(x, y) (x) * (y) // now MULT(3 + 2, 4 + 2) will expand to (3 + 2) * (4 + 2)
除非你的宏有更多,否则它似乎不会影响你当前的情况。
如果您的宏中有运算符,这一点非常重要。 例如:
#define ADD(x,y) x + y ADD(1,2) * 3 /* Should be 9, is 7 */
应该:
#define ADD(x,y) (x + y) ADD(1,2) * 3 /* 7 */
这些优先级问题也适用于@Gi Joe所说的参数,并且需要包含在parens中以获得优先级。
但是,对于像这样的宏:
#define MAGICNUM 3
没关系。
要记住的一件重要事情是预处理器只是扩展宏。 例如,如果您有以下行:
#define AD0_COMPARETIME_1 (AD0_ADMD_CT) #define AD0_COMPARETIME_2 AD0_ADMD_CT num_1 = AD0_COMPARETIME_1; num_2 = AD0_COMPARETIME_2;
在第一次扩展之后你会有这个:
num_1 = (AD0_ADMD_CT); num_2 = AD0_ADMD_CT;
在第二次扩展之后你会有这个:
num_1 = ((IO_AD1.ADMD.bit.CT)); num_2 = (IO_AD1.ADMD.bit.CT);
当扩展表达式时,如其他答案中所述,可能出现问题。