为什么这会创建一个无限的负奇数列表?

Why does this create an infinite list of negative odd numbers?

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

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

原因是 i-- 是一个 post 递减运算符。意思是,i 的值用在表达式中,然后是表达式本身的求值。这会导致您比较中的 i 值与打印语句中存在的值不同,从而形成无限循环。

  1. i-- Post 递减操作,告诉该值被使用 首先是表达式求值。
  2. --i 预减操作告诉表达式是 首先求值,然后使用表达式的结果。
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
...

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

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

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

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

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

在每次迭代中,i 递减 2 次,这就是系列 1、-1、-3 等。始终为正值,这会导致无限循环。如果您选择 i=2,那么系列将为 2、0,仅此而已。得到零后 while 循环将退出。

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

标准规定 int 需要至少能够表示 −3276732767 的范围。

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

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

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

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

只要 i 不为零,while 条件就始终为真,这里就是这种情况,因为 i 在第一次迭代时递减 2,并且此后 i 为负。

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

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

会在某个时候停止。

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