【问题标题】:Unexpected output in c [duplicate]c中的意外输出[重复]
【发布时间】:2013-07-07 08:09:45
【问题描述】:

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

【问题讨论】:

  • 将其通过预处理器,应用初等数学,然后后悔没有遵守“始终为宏参数加上括号”的规则。哦,下次在使用宏之前要三思。然后不要使用宏,而是编写一个(可能是inline)函数。
  • 必须是#define mult(a,b) ((a)*(b))。这就是问题所在。

标签: c output


【解决方案1】:

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))

另请阅读:So, what's wrong with using macros?,作者 Bjarne Stroustrup。

【讨论】:

  • 应该是((a)*(b))
【解决方案2】:

这是因为 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))

【讨论】:

  • 不,你没有。应该是((a)*(b))
  • @AseemBansal 做到了! :)
【解决方案3】:

在宏定义中使用括号

#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】:

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

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

    给出正确答案。

    【讨论】:

    • 不。尝试将其更改为((a)*(b)),以便习惯始终将所有内容括起来的习惯。
    • 没有。这不是一个很好的理由。不合理且没有得到正确解释的习惯是不成立的。
    • @iionela.voinescu -- 呃,不合理?为什么?这个问题还不够合理吗?另外,read this,里面有很多很好的理由给内容加上括号。
    • 用户如何发布问题说他是 C 编程的新手。我不需要向我解释你的评论,但他可能会。而不是仅仅说这是一个好习惯,您应该在单独的答案中正确地解释为什么会这样。如果解释得当,这类事情在某人的脑海中总是会更好。
    猜你喜欢
    • 2017-10-07
    • 2016-11-14
    • 2015-12-02
    • 1970-01-01
    • 2013-02-02
    • 2012-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多