【问题标题】:Why is "i" variable getting incremented twice in my program?为什么“i”变量在我的程序中增加了两次?
【发布时间】:2011-02-03 10:40:40
【问题描述】:

我的一个朋友向我展示了这个程序,并问我为什么i 变量会增加两次。

根据我的理解MAX(i++, ++j);在这一行i是先作为参数发送然后递增,所以如果i的初始值为10那么递增的值应该是11,但是它将i 的增量值显示为12

程序:

#include<stdio.h>

#define MAX(x,y) (x)>(y)?(x):(y)

void main(void)
{
    int i = 10;
    int j = 5;
    int k = 0;

    k = MAX(i++, ++j);

    printf("%d %d %d",i,j,k);
}

输出:

12 6 11

有人可以解释一下这个值是如何增加到 12 的吗?

谢谢。

【问题讨论】:

  • 还要记住main 应该返回一个int
  • 当然,这一定是之前某个问题的重复?
  • @larsmans 可能是我,我什至不知道究竟要搜索什么问题。
  • 这是个好问题。我很惊讶我自己找不到副本,而且显然没有其他人找到它。
  • 不要将宏用于三元运算符表达式

标签: c macros


【解决方案1】:

MAX 是一个宏,而不是一个函数。在您的用例中,它扩展为:

k = (i++) > (++j) ? (i++) : (++j);

【讨论】:

    【解决方案2】:

    你的宏替换意味着你写(i++)&gt;(++j)?(i++):(++j)

    【讨论】:

      【解决方案3】:

      您的宏定义包含两次参数

      #define MAX(x,y) (x)>(y)?(x):(y)
      

      这让

       k = MAX(i++, ++j);
      

      展开

      k = (i++)>(++j)?(i++):(j++);
      

      因此,递增两次。

      【讨论】:

        【解决方案4】:

        MAX 不是函数。 i 不作为参数发送。

        MAX 是一个宏。它在使用的地方被文本替换:

        k = (i++)>(j++)?(i++):(j++)
        

        现在你知道为什么它会增加两次。

        【讨论】:

          【解决方案5】:

          宏做简单的文本替换,所以在宏展开后,k = MAX(i++, ++j); 行被编译器视为:

          k = (i++)>(++j)?(i++):(++j);
          

          【讨论】:

            【解决方案6】:

            您的 MAX 宏扩展为

            (i++)>(++j)?(i++):(++j)
            

            说明为什么你得到一个双倍的增量。

            【讨论】:

              【解决方案7】:

              宏将扩展为类似于伪 C 代码的内容:

              if( i++ > j++)  // i is incremented the first time,  j is incremented once
                 return i++;  // i is incremented the second time
              else
                 return j++;  // we never go there, so j is not incremented twice
              

              【讨论】:

                【解决方案8】:

                使用MAX(i++, ++j)时,生成的代码为:

                (i++) > (++j) ? (i++) : (++j)
                

                使用预处理器宏只需扩展代码并将参数复制/粘贴到位。在这种情况下,您可能需要使用函数。

                int max(int x, int y)
                {
                  return (x > y ? x : y);
                }
                

                现代编译器将内联它,同时尊重函数调用的原始行为。

                【讨论】:

                  猜你喜欢
                  • 2020-10-24
                  • 2021-09-26
                  • 2011-10-06
                  • 2012-04-25
                  • 2015-07-04
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-05-04
                  相关资源
                  最近更新 更多