for
for 把“初始化、条件判断、步进表达式”集中写在一行,是 C 中最常见的计数循环结构。它与 while 可以互相改写,但在边界控制上通常更紧凑。
1. 基本语法
for (init; condition; step) {
statement;
}2
3
运行结果:该代码块主要用于语法或结构说明,单独运行通常无终端输出。
执行顺序是:先执行 init,再判断 condition;若条件非零就执行循环体,然后执行 step,再回到条件判断。
2. 示例
#include <stdio.h>
int main(void) {
int sum = 0;
for (int i = 1; i <= 100; ++i) {
sum += i;
}
printf("%d\n", sum);
return 0;
}2
3
4
5
6
7
8
9
10
11
12
可能的输出(示例):
<输出与输入或平台相关,请以实际运行为准>
这里把循环控制对象 i 的生命周期限制在 for 语句内部,减少了作用域泄露。
3. 常见变体
for (;;) 表示无限循环;三个表达式都可以省略,但分号必须保留。省略任何一项都应有明确意图,否则会降低可读性。
4. 实践建议
循环体中若出现多重 continue 或复杂分支,优先保证“步进表达式”仍然可预测。必要时把复杂逻辑拆成函数,避免把 for 退化为难以维护的控制流拼图。
5. 逆序循环的边界
for 写逆序遍历时,若索引类型是无符号整型,要特别注意下溢边界。下面这种写法更稳妥:
#include <stddef.h>
void visit_reverse(const int *a, size_t n) {
for (size_t i = n; i > 0; --i) {
int v = a[i - 1];
(void)v;
}
}2
3
4
5
6
7
8
运行结果:该代码块主要用于语法或结构说明,单独运行通常无终端输出。
它通过 i > 0 保证 i - 1 总是有效索引,避免把无符号对象减到极大值后继续循环。
6. 多控制表达式写法
for 还可以在初始化和步进位置维护多个控制对象。这种写法在双指针扫描、窗口移动等场景中很常见,但要保证每个控制对象的职责清晰。
#include <stdio.h>
int main(void) {
for (int left = 0, right = 4; left <= right; ++left, --right) {
printf("(%d, %d)\n", left, right);
}
return 0;
}2
3
4
5
6
7
8
可能的输出(示例):
<输出与输入或平台相关,请以实际运行为准>
当控制对象过多时,建议提炼出辅助函数,避免把 for 头部堆成难读表达式。
7. continue 与步进表达式
for 中执行 continue 时,不会直接回到条件判断,而是先执行 step,再进入下一轮条件检查。这个语义在“步进里包含资源更新”时尤为关键:若你把关键更新动作只写在循环体尾部,continue 可能绕过它;把每轮都必须执行的推进动作放在 step 中,路径会更稳定。
8. 循环控制对象保持单一职责
计数型 for 最怕“控制对象既管迭代,又承载业务状态”。一旦同一对象同时被循环头和循环体多处修改,边界就会迅速变得难以验证。更清晰的做法是:循环控制只负责遍历,业务状态使用独立对象承载,这样退出条件和计算语义都更直观。