循环结构概述
循环结构是程序设计中用于重复执行特定代码块的基本控制结构。当某个条件满足时,循环体内的代码会被重复执行,直到条件不再满足为止。C语言提供了三种循环语句:for语句 、while语句 和do-while语句。
循环结构的基本要素
- 循环初始化:设置循环控制变量的初始值
- 循环条件:决定循环是否继续执行的条件表达式
- 循环体:需要重复执行的代码块
- 循环更新:修改循环控制变量的值,使循环能够趋近于结束
for循环语句
标准格式
c
for (表达式1; 表达式2; 表达式3) {
// 循环体
}
执行流程
- 执行表达式1(初始化表达式),只执行一次
- 判断表达式2 (条件表达式)的值:
- 若为真(非0),执行循环体
- 若为假(0),跳出循环
- 执行循环体后,执行表达式3(更新表达式)
- 返回步骤2,继续判断表达式2
for循环的执行流程图解
开始
↓
执行表达式1(初始化)
↓
判断表达式2(条件)
↓
条件为真?─────┐
↓ 是 否
执行循环体 ↓
↓ 结束循环
执行表达式3(更新)
↓
返回判断表达式2
for循环的特点
- 三个表达式均可省略,但分号必须保留
- 表达式1:通常用于初始化循环控制变量
- 表达式2:循环继续执行的条件
- 表达式3:通常用于更新循环控制变量
for循环示例
计算1~50的累加和
c
#include <stdio.h>
int main(void) {
int sum = 0;
// 标准for循环
for (int i = 1; i <= 50; i++) {
sum += i; // 等价于 sum = sum + i
}
printf("1~50的和为:%d\n", sum);
return 0;
}
特殊for循环形式
无限循环(死循环)
c
// 形式1:三个表达式都为空
for (;;) {
// 循环体
// 需要使用break语句才能退出
}
// 形式2:条件恒为真
for (;1;) {
// 循环体
}
省略表达式的for循环
c
int i = 1; // 初始化放在循环外
for (; i <= 10;) {
printf("%d ", i);
i++; // 更新放在循环体内
}
for循环嵌套
示例:投掷两个骰子的所有组合
c
#include <stdio.h>
int main(void) {
printf("两个骰子点数组合(和大于7):\n");
printf("骰子1\t骰子2\t总和\n");
// 外层循环控制第一个骰子
for (int dice1 = 1; dice1 <= 6; dice1++) {
// 内层循环控制第二个骰子
for (int dice2 = 1; dice2 <= 6; dice2++) {
int sum = dice1 + dice2;
if (sum > 7) {
printf("%d\t%d\t%d\n", dice1, dice2, sum);
}
}
}
return 0;
}
while循环语句
标准格式
c
while (条件表达式) {
// 循环体
}
执行流程
- 判断条件表达式的值
- 如果条件为真(非0),执行循环体
- 执行完循环体后,返回步骤1
- 如果条件为假(0),结束循环
while循环的特点
- 先判断,后执行:可能一次都不执行循环体
- 适合循环次数不确定的情况
- 需要在循环体内更新循环控制条件
while循环示例
计算两个年份之间的闰年数量
c
#include <stdio.h>
int main(void) {
int year1, year2;
int count = 0; // 闰年计数器
printf("请输入两个年份:");
scanf("%d %d", &year1, &year2);
// 确保year1 <= year2
if (year1 > year2) {
int temp = year1;
year1 = year2;
year2 = temp;
}
// 遍历所有年份
int current = year1;
while (current <= year2) {
// 判断闰年:能被4整除但不能被100整除,或者能被400整除
if ((current % 4 == 0 && current % 100 != 0) || current % 400 == 0) {
printf("%d是闰年\n", current);
count++;
}
current++; // 更新循环变量
}
printf("%d年到%d年之间有%d个闰年\n", year1, year2, count);
return 0;
}
while循环的特殊形式
无限循环
c
while (1) {
// 循环体
// 需要使用break语句才能退出
}
空循环体
c
// 等待直到条件为假
while (条件表达式); // 注意:这里的分号就是空循环体
for循环与while循环的等价转换
c
// for循环形式
for (表达式1; 表达式2; 表达式3) {
循环体;
}
// 等价的while循环形式
表达式1;
while (表达式2) {
循环体;
表达式3;
}
do-while循环语句
标准格式
c
do {
// 循环体
} while (条件表达式); // 注意:这里的分号不能省略
执行流程
- 执行循环体(无条件执行一次)
- 判断条件表达式的值
- 如果条件为真,返回步骤1
- 如果条件为假,结束循环
do-while循环的特点
- 先执行,后判断:至少执行一次循环体
- 适合需要先执行一次再判断的情况
- 常用于菜单选择、输入验证等场景
do-while循环示例
菜单选择系统
c
#include <stdio.h>
int main(void) {
int choice;
do {
// 显示菜单
printf("\n=== 学生管理系统 ===\n");
printf("1. 添加学生\n");
printf("2. 删除学生\n");
printf("3. 查询学生\n");
printf("4. 退出系统\n");
printf("请选择操作(1-4):");
scanf("%d", &choice);
// 处理用户选择
switch (choice) {
case 1:
printf("执行添加学生功能...\n");
break;
case 2:
printf("执行删除学生功能...\n");
break;
case 3:
printf("执行查询学生功能...\n");
break;
case 4:
printf("感谢使用,再见!\n");
break;
default:
printf("输入错误,请重新选择!\n");
}
} while (choice != 4); // 当用户选择4时退出
return 0;
}
do-while与while的等价转换
c
// do-while形式
do {
循环体;
} while (条件);
// 等价的while形式(保证至少执行一次)
循环体;
while (条件) {
循环体;
}
三种循环语句的对比与选择
对比总结
| 特性 | for循环 | while循环 | do-while循环 |
|---|---|---|---|
| 执行顺序 | 先判断后执行 | 先判断后执行 | 先执行后判断 |
| 最少执行次数 | 0次 | 0次 | 1次 |
| 适用场景 | 循环次数已知 | 循环次数未知 | 至少执行一次 |
| 初始化位置 | 表达式1中 | 循环体外 | 循环体外 |
| 条件位置 | 表达式2 | while后括号内 | while后括号内 |
| 更新位置 | 表达式3 | 循环体内 | 循环体内 |
选择建议
-
使用for循环:
- 循环次数已知
- 需要明确的初始化、条件和更新
- 遍历数组、集合等
-
使用while循环:
- 循环次数未知
- 条件判断复杂
- 读取文件直到结束
- 等待用户输入特定值
-
使用do-while循环:
- 至少需要执行一次
- 菜单选择界面
- 输入验证
循环控制语句
break语句
- 功能:立即跳出当前循环
- 适用:for、while、do-while循环
- 注意:只能跳出一层循环
continue语句
- 功能:跳过本次循环剩余部分,直接开始下一次循环
- 适用:for、while、do-while循环
- 注意:在for循环中,continue后仍会执行表达式3
示例:break和continue的使用
c
#include <stdio.h>
int main(void) {
printf("break示例:找到第一个3的倍数就停止\n");
for (int i = 1; i <= 10; i++) {
if (i % 3 == 0) {
printf("找到:%d\n", i);
break; // 找到后立即退出循环
}
printf("检查:%d\n", i);
}
printf("\ncontinue示例:跳过所有3的倍数\n");
for (int i = 1; i <= 10; i++) {
if (i % 3 == 0) {
continue; // 跳过本次循环剩余部分
}
printf("%d ", i);
}
printf("\n");
return 0;
}
实际编程建议
1. 避免无限循环
除非确实需要,否则应避免无限循环。如果使用无限循环,确保有明确的退出条件。
2. 注意循环变量的更新
确保循环变量在循环体内被正确更新,避免死循环。
3. 合理使用循环嵌套
循环嵌套层数不宜过多(一般不超过3层),否则会影响代码可读性和性能。
4. 优化循环效率
- 将不变的计算移到循环外
- 减少循环内部的函数调用
- 使用合适的循环类型