"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
中的三个参数(initialization
、condition
和increment
)是可选的(但它们仍然需要分号;
)。所以,你可以安全地写 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
),因为我们从未达到增量语句。
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
中的三个参数(initialization
、condition
和increment
)是可选的(但它们仍然需要分号;
)。所以,你可以安全地写 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
),因为我们从未达到增量语句。