【问题标题】:C #define macrosC#define 宏
【发布时间】:2009-01-26 19:02:07
【问题描述】:

这就是我所拥有的,我想知道它是如何工作的以及它实际上做了什么。

#define NUM 5
#define FTIMES(x)(x*5)

int main(void) {
    int j = 1;
    printf("%d %d\n", FTIMES(j+5), FTIMES((j+5)));
}

它产生两个整数:26 和 30。

它是怎么做到的?

【问题讨论】:

    标签: c c-preprocessor operator-precedence


    【解决方案1】:

    发生这种情况的原因是因为您的宏将打印扩展到:

    printf("%d %d\n", j+5*5, (j+5)*5);
    

    意思:

    1+5*5 and (1+5)*5
    

    【讨论】:

    • 这应该教给我们一个宝贵的教训,即避免为内联函数实际处理的事情使用#define 宏。
    • 或者,当您无法避免它们时,将每个参数的每次出现都放在括号中,并将整个宏放在括号中(也就是说,当您的宏是表达式而不是语句时)
    【解决方案2】:

    由于还没有提到,解决这个问题的方法如下:

    #define FTIMES(x) ((x)*5)
    

    宏展开中x 周围的括号可防止运算符关联性问题。

    【讨论】:

    • 如果您在宏中多次出现该参数并且您传入某种具有副作用的表达式(例如 j += 3),这将无法拯救您。
    【解决方案3】:

    define 只是一个字符串替换。

    之后你的问题的答案是操作顺序:

    FTIMES(j+5) = 1+5*5 = 26

    FTIMES((j+5)) = (1+5)*5 = 30

    【讨论】:

      【解决方案4】:

      编译器预处理只是简单地替换它所看到的 FTIMES,然后编译代码。所以实际上编译器看到的代码是这样的:

      #define NUM 5
      #define FTIMES(x)(x*5)
      
      int main(void)
      {
      
          int j = 1;
      
          printf("%d %d\n", j+5*5,(j+5)*5);
      }
      

      然后,考虑到运营商的偏好,您可以看到为什么会得到 26 和 30。

      【讨论】:

      • 技术上,编译器看不到#defines。 :)
      【解决方案5】:

      如果你想修复它:

      #define FTIMES(x) ((x) * 5)
      

      【讨论】:

        【解决方案6】:

        预处理器将代码中所有出现的 NUM 替换为 5,并将所有 FTIMES(x) 替换为 x * 5。然后编译器编译代码。

        它只是文本替换。

        【讨论】:

          【解决方案7】:

          操作顺序。

          FTIMES(j+5) 其中 j=1 计算结果为:

          1+5*5

          这是:

          25+1

          =26

          通过制作 FTIMES((j+5)) 您已将其更改为:

          (1+5)*5

          6*5

          30

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-08-27
            • 2020-09-26
            • 2010-10-20
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多