【问题标题】:C Macro BehaviorC 宏行为
【发布时间】:2013-06-09 06:31:07
【问题描述】:

我有以下简单的 C 代码

#define Sqrt(A) A * A


int main(void) {

    int A = 10;

    int x = Sqrt(A+1);

    return 0;

}

由于某种原因,当我这样使用它时,使用 A+1,我得到 x 为 21,这可能是 10+11。 我的问题是,乘法是如何被忽略的? 如果我用宏文本切换宏,我会得到正确的结果,即 121。

谢谢。

【问题讨论】:

  • 始终在宏变量周围加上括号。请记住,它们在编译之前被扩展,因此任何可能导致奇怪的操作顺序的扩展都可能发生。括号停止。
  • 正是这种行为让一些人讨厌宏。如果你能找到宏的替代方法(比如定义一个函数),你应该认真考虑一下(如果你还没有的话)。

标签: c macros


【解决方案1】:

首先,您的Sqrt 命名错误,应该是Square(不是平方根

然后,生成预处理的表单(即使用gcc -C -E)并查看其中的内容。

 #define Sqr(A) A * A

 int a = 10;

 int x = Sqr(a+1);

最后一行扩展为

 int x = a+1 * a+1;

解析为

 int x = a+(1*a)+1;

故事的寓意,总是在宏定义中使用额外的括号,即

 #define Sqr(A) ((A)*(A))

即使有这样的定义,Sqr(a++) 也可能是未定义的行为,至少是顽皮的。

所以你想避免使用宏,实际上,学习使用内联函数,比如

 inline int square(int a) { return a*a; };

顺便说一句,您需要将其设为 static inline 而不仅仅是 inline(并将其放入头文件中)

【讨论】:

    【解决方案2】:

    'cos

    #define Sqrt(A) A * A
    

    制作

    Sqrt(A+1);
    

    翻译成

    A + 1 * A + 1
    

    A 是 10

    所以你得到

    10 + 1 * 10 + 1

    现在算一算!

    顺便说一句,sqrt 似乎说平方根不是平方的!

    【讨论】:

      【解决方案3】:

      您将宏定义为A * A。因此,Sqrt(A + 1) 扩展为 A + 1 * A + 1,即由于运算符优先级,等于 2 * A + 1 - 你得到了 2 * 10 + 1 = 21

      这就是为什么您应该始终将宏及其参数括起来:

      #define Sqrt(A) ((A) * (A))
      

      顺便说一句,为什么是宏?如果有一天你写Sqrt(A++)怎么办?然后你可以期待nasal demons。写一个内联函数会更安全(可怕的dictu,一个正确命名的内联函数):

      static inline double square(double x)
      {
          return x * x;
      }
      

      【讨论】:

        【解决方案4】:

        在宏内部,A 被替换为传入宏调用的任何内容。在这种情况下,即A+1。这意味着宏被扩展为:

        A+1 * A+1
        

        由于运算符优先级,这被解释为A + 1*A + 110 + 10 + 1 = 21

        【讨论】:

          【解决方案5】:

          您应该将宏定义为#define Sqrt(A) ((A) * (A))

          【讨论】:

            【解决方案6】:

            BODMAS 规则哥们!!正如前面的答案所暗示的那样。乘法发生在你的加法之前。 您的操作 Sqrt(A+1) 其中 A = 10 将评估为 10+1*10+1 10+10+1 21!!

            【讨论】:

              【解决方案7】:

              宏被逐字替换然后求值。

              由于乘法的优先级高于加法,因此当您将A+1 赋予宏时,它变为10 + 1 * 10 + 1 => 10 + 10 + 1 => 21

              同样如果你给A+2 ..... 10 + 2 * 10 + 2 => 10 + 20 + 2 => 32.

              【讨论】:

                【解决方案8】:
                when you call x = MACRO_NAME(A+1); this statement is replace as x = A + 1 * A + 1
                in c priority of multiplication is more than addition so it will be 1st executed 1*A which give as A, then A+A+1 will give you result as 21`enter code here`
                i.e  A+1*A+1 
                  =  A+A+1 
                  =  21
                for proper answer you need to write Macro as #define MACRO_NAME(A) (A) * (A) which give you result as 
                121
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-12-24
                  • 2014-06-06
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多