c 中的意外输出

我是c语言的新手。 我只是想知道为什么我的宏不能正常工作。 它输出为13,我的预期输出为24。

#include #define mult(a,b) a*b int main() { int x=4,y=5; printf("%d",mult(x+2,y-1)); return 0; } 

在宏定义中使用括号

 #include #define mult(a,b) ((a)*(b)) int main() { int x=4,y=5; printf("%d",mult(x+2,y-1)); return 0; } 

这是因为不同的算术运算符具有不同的优先级。 因此,在定义宏时始终使用括号。

mult(x+2,y-1)扩展为x +2 * y -1 ,等于4 + 2 * 5 -1得到输出: 13

您可能期待答案(4 + 2) * (5 -1) = 6 * 4 = 24 。 为了使它像这样展开,你应该写@heffCo3也建议使用parenthesize宏:

 #define mult(a,b) ((a)*(b)) 

Read aslo: 那么,使用宏有什么问题? 作者:Bjarne Stroustrup。

这是因为C宏是简单的文本替换,宏编写器必须确保在替换每个宏变量时围绕每个宏变量插入括号,并围绕宏扩展本身,以防止由此产生的扩展带来新的含义。

如果你观察你的程序: mult(a, b)被定义为a * b

 mult(x + 2, y - 1) = x + 2 * y - 1 = 4 + 2 * 5 - 1 = 4 + 10 - 1 = 13 

正确的方法是:

 mult(a, b) ((a) * (b)) 

因为它字面上替换了参数:

 mult(x+2,y-1) --> mult(4+2,5-1) --> 4 + 2*5 - 1 --> 13 

尝试将定义更改为:

 #define mult(a,b) (a)*(b) 

在这种情况下,预处理后的结果是:

 int main() { int x=4,y=5; printf("%d",(x+2)*(y-1)); return 0; } 

这将解决问题,但它仍然不是最好的方法。

 #define mult(a,b) ((a)*(b)) 

这个版本被认为是一种很好的做法,因为在其他类型的情况下,第一个版本会失败。 见下面的例子:

 #include #define add(a,b) (a)+(b) int main() { int x=4,y=5; printf("%d",add(x+2,y-1)*add(x+2,y-1)); return 0; } 

在这种情况下,它会给出一个不正确的答案,因为它由预处理器转换为hibernate:

 int main() { int x=4,y=5; printf("%d",(x+2)+(y-1)*(x+2)+(y-1)); return 0; } 

打印34而不是100。
对于((a)+(b))版本,它将转换为:

 int main() { int x=4,y=5; printf("%d",((x+2)+(y-1))*((x+2)+(y-1))); return 0; } 

给出正确的答案。