2

我是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;
}
4

4 回答 4

6

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。

于 2013-07-09T16:06:19.617 回答
5

这是因为 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))
于 2013-07-09T16:07:19.867 回答
2

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

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;
}

给出正确答案。

于 2013-07-09T16:07:22.883 回答
2

在宏定义中使用括号

#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;
}

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

于 2013-07-09T16:07:43.633 回答