C语言学习笔记(从入门到精通) 第7部分
循环结构:for、do-while、break、continue、goto
C语言中实现重复执行代码的主要方式就是循环语句。本节重点讲解最常用的三种循环以及控制循环流程的关键语句。
1. for 循环(最常用)
语法格式:
for (初始化表达式; 条件表达式; 增量表达式)
{
循环体语句;
}
执行流程:
- 先执行初始化表达式(只执行一次)
- 判断条件表达式是否为真
- 如果为真 → 执行循环体 → 执行增量表达式 → 回到第2步
- 如果为假 → 跳出循环
经典写法示例:
#include <stdio.h>
int main()
{
// 打印 1 到 10
for (int i = 1; i <= 10; i++)
{
printf("%d ", i);
}
printf("\n");
// 求 1+2+...+100
int sum = 0;
for (int i = 1; i <= 100; i++)
{
sum += i;
}
printf("1+2+...+100 = %d\n", sum);
return 0;
}
for 循环的几种常见变体:
// 1. 省略初始化(已经在外面定义了变量)
int i = 1;
for (; i <= 10; i++) { ... }
// 2. 省略条件(相当于 while(1) 死循环)
for (int i = 0; ; i++) { ... }
// 3. 省略增量(在循环体内自己改)
for (int i = 0; i < 10; )
{
printf("%d ", i);
i += 2; // 步长 2
}
// 4. 完全空 for(死循环)
for (;;) { ... } // 等价于 while(1)
2. while 循环 与 do-while 循环
while 循环(先判断后执行)
while (条件表达式)
{
循环体;
}
do-while 循环(先执行后判断,至少执行一次)
do
{
循环体;
} while (条件表达式);
注意:最后的分号 ; 一定不能忘!
三者对比示例(输入正整数,输入负数或0结束)
#include <stdio.h>
int main()
{
int num;
// 方式1:while 先判断
printf("while 版本(可能一次都不执行):\n");
printf("请输入正整数(输入<=0结束):");
scanf("%d", &num);
while (num > 0)
{
printf("你输入了:%d\n", num);
printf("请输入正整数(输入<=0结束):");
scanf("%d", &num);
}
// 方式2:do-while 先执行
printf("\ndo-while 版本(至少执行一次):\n");
do
{
printf("请输入正整数(输入<=0结束):");
scanf("%d", &num);
if (num > 0)
{
printf("你输入了:%d\n", num);
}
} while (num > 0);
return 0;
}
小结:什么时候用哪种循环?
- 确定循环次数 → 优先用
for - 不确定循环次数,但至少执行一次 → 用
do-while - 不确定循环次数,先判断条件 → 用
while
3. break 和 continue
break:立即跳出当前所在的循环(彻底结束循环)
continue:结束本次循环,立刻进入下一次循环(跳过本次循环剩余部分)
对比示例(打印 1~20 中不是 3 的倍数的数字)
#include <stdio.h>
int main()
{
printf("使用 continue 跳过 3 的倍数:\n");
for (int i = 1; i <= 20; i++)
{
if (i % 3 == 0)
{
continue; // 跳过本次循环,i++ 继续下一轮
}
printf("%d ", i);
}
printf("\n\n");
printf("使用 break 在遇到 15 就结束:\n");
for (int i = 1; i <= 20; i++)
{
if (i == 15)
{
break; // 直接结束整个循环
}
printf("%d ", i);
}
printf("\n");
return 0;
}
多层循环中 break 只跳出最近的一层
for (int i = 1; i <= 3; i++)
{
for (int j = 1; j <= 5; j++)
{
if (j == 3) break; // 只跳出 j 这一层循环
printf("i=%d, j=%d\n", i, j);
}
}
4. goto 语句(不推荐使用,但要了解)
语法:
goto 标签名;
...
标签名:
语句;
常见两种用法(了解即可):
// 用法1:跳出多层循环(替代多层 break)
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (某种很深的条件成立)
{
goto END; // 直接跳到最外层结束
}
}
}
END:
printf("结束\n");
// 用法2:简化某些错误处理(早期代码常见)
if (打开文件失败) goto ERROR;
if (读取失败) goto ERROR;
...
ERROR:
printf("发生错误\n");
return -1;
现代编程观点:
- 强烈不推荐在普通业务逻辑中使用
goto - 99% 的
goto都可以用结构化方式(break、continue、函数返回、异常处理等)替代 - 唯一合理场景:多层嵌套跳出 或 C语言中集中错误处理(但现代写法更推荐用函数封装)
总结对比表
| 语句 | 作用 | 跳出范围 | 是否推荐 | 典型使用场景 |
|---|---|---|---|---|
for | 次数确定、计数型循环 | — | ★★★★★ | 几乎所有计数循环 |
while | 条件型,先判断 | — | ★★★★ | 未知次数,需先判断条件 |
do-while | 条件型,至少执行一次 | — | ★★★ | 至少执行一次的交互场景 |
break | 立即结束整个循环 | 当前所在循环 | ★★★★★ | 找到目标、异常退出 |
continue | 跳过本次循环剩余部分 | 当前本次循环 | ★★★★ | 过滤掉某些不符合条件的项 |
goto | 无条件跳转到指定标签 | 任意位置(危险) | ☆☆☆ | 极少数多层跳出/错误集中处理 |
下一节建议学习内容:
- 循环嵌套与经典案例(打印三角形、九九乘法表、质数判断等)
- 随机数生成(rand() 和 srand())
有任何不明白的地方或想看具体练习题,都可以直接问我!