我是c语言的新手。我只是想知道为什么我的宏不能正常工作。它给我的输出是 13,而我的预期输出是 24。?
#include<stdio.h>
#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
。要使其像这样扩展,您应该将括号宏编写为@H2Co3 还建议:
#define mult(a,b) ((a)*(b))
另请阅读:那么,使用宏有什么问题?通过 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<stdio.h>
#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;
}
在这种情况下,它会给出一个不正确的答案,因为它被预处理器翻译成以下内容:
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;
}
给出正确答案。
在宏定义中使用括号
#include<stdio.h>
#define mult(a,b) ((a)*(b))
int main()
{
int x=4,y=5;
printf("%d",mult(x+2,y-1));
return 0;
}
这是因为不同的算术运算符具有不同的优先级。因此在定义宏时总是使用括号。