【问题标题】:Why does this create an infinite list of negative odd numbers?为什么这会创建一个无限的负奇数列表?
【发布时间】:2020-11-09 21:21:25
【问题描述】:

如果 i=1,为什么下面的指令会创建一个无限的负数列表(-1、-3、-5、...)?

while (i--)
  printf("\n%i", --i);

【问题讨论】:

  • 技术上它不是无限的,它会一直持续到你通过INT_MIN,然后有一些实现定义的行为。但是对于你的问题,为什么不呢。你希望它做什么?
  • 您应该提及您关注的重点是什么。它是对您认为应该是错误的 while 循环的真实评估,还是只是为什么它分两步打印负数。您会看到我们已经提供了答案,但并非所有人都专注于一件事。
  • @ThomasJager:C 标准说整数溢出的行为是未定义的,这意味着它不强加任何要求。这包括它不需要实现来定义行为这一事实,因此只有在实现选择定义行为时,行为才是实现定义的。
  • 我认为 printf() 中的 -- 运算符只会更改 i 用于打印的值,而不是变量本身的值(这里是初学者)。知道这一切就清楚了。非常感谢大家的回答。 (如果我的英语不是完美的,我很抱歉,这不是我的母语)

标签: c infinite


【解决方案1】:

原因是i-- 是一个后减运算符。意思是,i 的值用于表达式,然后是表达式本身的评估。这会导致比较中 i 的值与 print 语句中存在的值不同,从而导致无限循环。

  1. i-- 后递减操作告诉该值被使用 首先是表达式求值。
  2. --i 预减操作告诉表达式是 首先求值,然后使用表达式的结果。

【讨论】:

    【解决方案2】:
    i = 1                        // 1
    while (i--)                  // value of 'i--' is 1 is true; side-effect i = 0
        printf("\n%i", --i);     // print value of '--i' ie -1, side-effect i = -1
    while (i--)                  // value of 'i--' is -1 is true; side-effect i = -2
        printf("\n%i", --i);     // print value of '--i' ie  -3, side-effect i = -3
    while (i--)                  // value of 'i--' is -3 is true; side-effect i = -4
        printf("\n%i", --i);     // print value of '--i' ie  -5, side-effect i = -5
    ...
    

    请注意,上面的副作用可能发生在表达式其余部分的评估之前或之后(甚至期间)。

    【讨论】:

      【解决方案3】:

      while 条件使用后减量。这意味着它测试i 的原始值,即1,然后将值递减为0。由于1 是真实的,所以它进入了循环。

      在循环内部,您打印--i。这是预减量,因此它将i 设置为-1,并打印该值。

      在下一次迭代中会发生同样的事情。它测试-1,它是真的,将其递减为-2,进入循环体,将其递减为-3,然后打印出来。

      i 溢出到最小的负数之下时,你的代码最终会遇到未定义的行为。在大多数实现中,它将环绕并继续相同的进程,但实际行为并不特定于语言。

      【讨论】:

        【解决方案4】:

        在每次迭代中,i 递减 2 次,即系列 1、-1、-3,依此类推。总是导致无限循环的正值。如果您选择 i=2 那么系列将是 2, 0 仅此而已。在while循环为零后将退出。

        【讨论】:

          【解决方案5】:

          i 似乎是 int 类型,并且是一个带符号整数,它也涵盖负范围。

          标准要求int 必须能够代表至少−3276732767 的范围。

          如果你减少它,值可以下降到INT_MIN

          如果在到达INT_MIN 的边界后减小该值,则行为未定义。

          i 在每次迭代中减少2,因此输出显示减少了 2er 步。

          循环是否无限取决于实现如何处理INT_MIN 之后的递减。

          只要i 不为零,while 条件始终为真,这里的情况是i 在第一次迭代时减 2,此后i 也是负数。

          【讨论】:

            【解决方案6】:

            因为您从奇数 2 中减去 2,所以在大多数实现中它永远不会为零。

            while (i--)
              if(i & 1) printf("\n%i", i);
            

            会在某个时候停止。

            【讨论】:

              【解决方案7】:

              没有什么特别的。你有负数的 i,它在开始时等于 1(然后是 -1,-3,-5,...),因为你将变量 i 减少了两次。首先,您在条件表达式中执行此操作:“while(i--)”。之后,它发生在 while 代码块中:“printf("\n%i", --i);"。最后,由于您正在使用 while 循环,它会一次又一次地减少 2。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2015-03-29
                • 2018-05-03
                • 1970-01-01
                • 1970-01-01
                • 2021-05-14
                • 1970-01-01
                • 2018-02-22
                • 1970-01-01
                相关资源
                最近更新 更多