所以我想知道什么时候使用
#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
答案 0 :(得分:6)
两者都没有区别。在第一种情况下,XXX
替换为yyy
,而(yyy)
则替换为第二种情况。使用包围的惯例是避免可能发生的逻辑错误。例如,您将添加功能定义为:
#define f(N) N+N
int a = f(5)*f(5)
预期值为10 * 10 = 100,但输出为35,因为在编译时变为
int a = 5+5*5+5,
所以使用操作员首选项规则,输出更改。
所以括号避免这些类型的错误。
答案 1 :(得分:3)
通过添加括号,您将强制括号内的参数在宏体的其余部分之前进行求值,因此如果您有
#define MULT(x, y) (x) * (y)
// now MULT(3 + 2, 4 + 2) will expand to (3 + 2) * (4 + 2)
除非您的宏有更多内容,否则它似乎不会影响您当前的情况。
答案 2 :(得分: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
没关系。
答案 3 :(得分:0)
要记住的一件重要事情是预处理器只是扩展宏。例如,如果您有以下行:
#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);
当表达式扩展时,可能会出现问题,如其他答案中所述。