在开始for
循环之前,循环变量是否得到更新?或者在for
循环的每次迭代结束时?
我尝试编写测试代码来自行解决,但我不确定它是否适合测试。
#include <stdio.h>
int main(void)
{
int i;
for (i = 0; i < 5; i++) // does i++ happen here
{
printf("%d\n", i); // or does it happen after this is executed?
}
return 0;
}
使用此while
循环,可以清楚变量的更新位置:
#include <stdio.h>
int main(void)
{
int j;
j = 0;
while (j < 5)
{
printf("%d\n", j);
j++; // j updates here
}
return 0;
}
提前致谢。
答案 0 :(得分:1)
根据标准 ISO / IEC 9899:2011信息技术 - 编程语言 - C§6.8.5.3/ 1 for语句 (Emphasis Mine):
声明
for ( clause-1 ; expression-2 ; expression-3 ) statement
表现如下:表达式表达式-2是 控制在每次执行之前计算的表达式 循环体。 表达式-3被评估为void 每次执行循环体后的表达式。如果子句-1是a 声明,它声明的任何标识符的范围是余数 声明和整个循环,包括其他两个 表达式;它是在第一个之前按执行顺序到达的 评估控制表达。如果第1条是一个 表达式,它在第一个之前被计算为void表达式 评估控制表达.137)
因此,增量发生在for循环的每次迭代结束时。
您还可以在以下示例中看到此信息。 for
循环最有可能由编译器实现,如goto
语句。请考虑以下代码:
int main(void) {
int i;
for (i = 0; i < 5; i++) {
}
}
此代码生成的汇编代码为:
main:
pushq %rbp
movq %rsp, %rbp
movl $0, -4(%rbp)
.L3:
cmpl $4, -4(%rbp)
jg .L2
addl $1, -4(%rbp)
jmp .L3
.L2:
movl $0, %eax
popq %rbp
ret
如果您专注于.L3
(即for
循环),您会注意到该陈述
addl $1, -4(%rbp)
是增量发生的地方(即++i
)。在该命令之后,跳回.L3
(即下一次迭代)。
答案 1 :(得分:1)
在循环体完成后,将评估表达式i++
。
功能上,形式的for循环
for (i = 0; i < 5; i++)
{
printf("%d\n", i);
}
与;
等效i = 0;
while (i < 5)
{
{
printf("%d\n", i);
}
i++;
}
答案 2 :(得分:1)
尽管我之前的回答是,我说的是废话,我建议你看看:postfix and prefix increment operator in a for loop
基本上上面的帖子归结为你的问题是增量发生在循环传递的结束处。
答案 3 :(得分:1)
expr1;
while (expr2) {
code;
expr3;
}
相当于
strlen
所以是的,增量发生在身体完成之后。以下是int strlen(char *s)
{
int i;
for (i = 0; s[i]; ++i)
;
return i;
}
int strlen(char *s)
{
int i;
i = 0;
while (s[i])
++i;
return i;
}
与:
相同lag
答案 4 :(得分:1)
与OP for
/ while
示例的唯一区别在于break
或continue
和范围规则会发生什么。
for ( clause-1 ; expression-2 ; expression-3 ) statement
表现得像
{
clause-1;
while (expression-2) {
{
statement;
// Should the statement contain a `continue` or `break`, then flow jumps as indicated.
// a `continue` goes to continue_label:
// a `break` goes to break_label:
}
continue_label:
expression-3;
}
break_label:
}
范围所需的额外外部{}
:clause-1
应该int x = 1;
与
int x = 1;
while (expression-2) {
但是喜欢
{
int x = 1;
while (expression-2) {
范围也需要最里面的{}
。检查以下代码的3 j
s。
int main(void) {
int j;
printf("1 %p\n", (void*) &j);
for (int j = 0;
printf("2 %p\n", (void*) &j), j < 3;
j++, printf("4 %p\n", (void*) &j)) {
int j;
printf("3 %p\n", (void*) &j);
}
return 0;
}
1 0x28ac1c
2 0x28ac18
3 0x28ac14
4 0x28ac18
2 0x28ac18
3 0x28ac14
4 0x28ac18
2 0x28ac18
3 0x28ac14
4 0x28ac18
2 0x28ac18
答案 5 :(得分:0)
在for循环中,每次迭代后都会完成增量。
while循环更可控,你可以在任何你想要的地方做到这一点!
答案 6 :(得分:0)
i++
发生在for循环体之后。根据{{3}},
for (initialize; test; step) statement
for语句首先计算表达式initialize。然后呢 评估表达式测试。如果test为false,则循环结束 语句后恢复程序控制。否则,如果是测试 如果是,则执行语句。最后,评估步骤,并且 循环的下一次迭代从再次评估测试开始。