"for (; --i >= 0; )" 在 C 中是什么意思?

What does "for (; --i >= 0; )" mean in C?

for (; --i >= 0; ) 在 C 中是什么意思?

计数器如何递减,它与 for ( ; i >= 0; --i) 有何不同?

for (; --i >= 0; ) 是这样工作的:

假设你将 i 设为 10,它将递减 i 值并比较 9 >= 0 等等。

所以输出会像 9, 8... till 0

虽然循环 for( ; i>=0;--i) 会首先转到 10,然后递减该值,然后它会检查 i>=0。所以输出将是 10, 9, 8... till 0.

这些结构在形式上等同于

while (--i >= 0)
{
  Body;
}

while (i >= 0)
{
  Body;

  --i;
}

你能看出区别吗?

第一个递减i然后检查条件。

第二个首先检查条件,如果为真,则在循环体执行后递减i

for中的三个参数(initializationconditionincrement)是可选的(但它们仍然需要分号;)。所以,你可以安全地写 for(;;) 并且它与 while(1) 相同。所以,像

这样的表达式

for(; x > y; x++) { ... }

for(;1;x++) { if(x > y) break;

for(;;) { if(x++ > y) break;

for(;x++ > y;) { ... }

有效且等效。在此,增量发生在条件参数中,就像在您的代码示例中一样。

嗯,跟说的一样for( i=0 or some value; --i <= 0 ; do nothing){} --i 是预减运算符。

也就是说当--i这段代码被读取时,i的值会同时减少1

它们很相似,但一样!首先,您必须了解 C 中的 for 循环是如何执行的:

举个例子:

      1      2, 5  4
      |      |     |
      v      v     v
for(i = 0; i < 5; i++) {
    // Do something <-- 3
}

如您所见,2、3、4、5 是一个循环,直到条件为假。


现在你应该清楚地看到for循环是如何执行的了。现在的不同之处在于,在您的第一个示例中:

int i = 5;
for ( ; --i >= 0; )
    printf("%d\n", i);

输出将是:

4
3
2
1
0

因为在第一次检查条件(第 2 点)之后,它会执行 for 语句的代码块并且 i 已经递减。

在你的第二个例子中:

int i = 5;
for( ; i>=0; --i)
    printf("%d\n", i);

输出将是:

5 // See here the difference
4
3
2
1
0

在这里你得到了差异,因为它在第 4 点递减,所以第一次运行时值为 5。

for 循环中包含三个主要组件。

初始化、条件和事后思考。

初始化在整个语句的开头发生一次。条件在每个周期 之前发生。每个周期 之后,事后才想到。考虑 i 从 2:

开始
for (; --i >= 0; )

Initialization: i = 2
Condition: i = 1
Afterthought: i = 1
Condition: i = 0
Afterthought: i = 0
Condition: i = -1
Exit

另一种情况

for( ; i>=0; --i)
Initialization: i = 2
Condition: i = 2
Afterthought: i = 1
Condition: i = 1
Afterthought: i = 0
Condition: i = 0
Afterthought: i = -1
Condition: i = -1
Exit

可以看到第二个版本居然多了一个周期!

通常,我们可以将任何 for 循环或 while 循环转换为一组带有 goto 的大部分线性语句。这样做可能有助于比较代码。

案例一

### for (; --i >= 0; ) { statements; }
  ;                            // Initializer statement
start:
  bool condition = (--i >= 0); // Conditional
  if (condition) {             // If true, we execute the body as so:
    statements;                // The statements inside the loop
    ;                          // Empty increment statement
    goto start                 // Go to the top of the loop.
  }

案例二

### for( ; i>=0; --i) { statements; }
  ;                            // Initializer statement
start:
  bool condition = (i >= 0);   // Conditional
  if (condition) {             // If true, we execute the body as so:
    statements;                // The statements inside the loop
    --i;                       // Increment statement
    goto start;                // Go to the top of the loop.
  }

让我们比较一下这两种情况下的 "simpler" 代码。

在第一种情况下,我们在每个循环体之前第一次递减i。在第二种情况下,我们在每个循环体之后递减i

了解这一点的最简单方法是考虑在 i == 0 时进入此循环时会发生什么。在第一种情况下,在此代码块之后,您将得到 i == -1 的结果值。在第二种情况下,i 不会改变(即 i == 0),因为我们从未达到增量语句。