C do…while 循环(千字长文)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
一、前言:为什么需要学习 do…while 循环?
在编程世界中,循环结构是解决问题的核心工具之一。无论是遍历数据、重复计算,还是实现交互式菜单,循环都能让代码高效地完成重复任务。C语言作为一门经典且广泛使用的编程语言,提供了三种主要的循环语句:for
、while
和 do…while
。其中,do…while
循环虽然不如 for
或 while
那么常用,但它独特的执行逻辑在特定场景下能发挥重要作用。
想象一下这样的场景:你正在开发一个需要用户输入验证的程序,比如登录界面。系统必须至少执行一次输入操作,即使用户第一次输入就正确,也需要确保界面能立即响应。这种“至少执行一次”的需求,正是 do…while
循环的强项。通过本文,我们将从基础语法到实际案例,系统性地解析这一循环结构。
二、循环结构的“三剑客”:do…while 的独特定位
在深入讲解 do…while
之前,我们先回顾 C语言的三种循环:
循环类型 | 执行流程 | 特点描述 |
---|---|---|
for | 初始化 → 条件判断 → 执行 → 更新 | 适合已知循环次数的场景 |
while | 条件判断 → 执行 → 重复判断 | 可能一次都不执行 |
do…while | 执行 → 条件判断 → 重复执行 | 至少执行一次循环体 |
从表格可以看出,do…while
的核心优势在于“先执行后判断”,这使其成为处理“必须至少运行一次”的场景的最佳选择。
三、do…while 的语法结构与执行流程
3.1 基础语法格式
do {
// 循环体:要重复执行的代码
} while (条件表达式);
3.2 执行流程的“三步曲”
- 执行循环体:无论条件如何,循环体内的代码至少执行一次。
- 条件判断:执行完循环体后,检查
while
后的条件表达式。 - 循环决策:若条件为真(非零值),则返回步骤1;若为假(零值),则退出循环。
比喻理解:这就像“先吃一口蛋糕,再决定要不要继续吃”。即使蛋糕难吃(条件不满足),你也已经尝过一口(循环体执行过)。
四、对比实验:do…while 与其他循环的差异
4.1 与 while 循环的对比
案例场景:要求用户输入一个正整数,直到输入正确为止。
// 使用 while 的写法
int number = 0;
printf("请输入一个正整数:");
scanf("%d", &number);
while (number <= 0) { // 初始条件判断可能导致循环体未执行
printf("输入错误,请重新输入:");
scanf("%d", &number);
}
问题:如果用户第一次输入就正确,while
的循环体不会执行,但程序逻辑是正确的。然而,如果初始输入错误,while
能正常循环。
do…while 的改进写法:
int number = 0;
do {
printf("请输入一个正整数:");
scanf("%d", &number);
} while (number <= 0);
优势:无论初始输入是否正确,do…while
都会确保至少执行一次输入流程,避免了 while
可能跳过的风险。
4.2 与 for 循环的对比
场景:计算 1 到 10 的和。
// for 循环
int sum = 0, i;
for (i = 1; i <= 10; i++) {
sum += i;
}
// do…while 的实现
int sum = 0, i = 1;
do {
sum += i;
i++;
} while (i <= 10);
结论:虽然 do…while
可以完成 for
的功能,但 for
更适合已知循环次数的场景。而 do…while
的价值在于“强制执行一次”的特性。
五、进阶用法:do…while 的实际应用场景
5.1 用户输入验证场景
#include <stdio.h>
int main() {
char choice;
do {
printf("请选择操作:1.查询 2.退出\n");
scanf(" %c", &choice); // 注意空格处理输入缓存
} while (choice != '2');
printf("程序退出\n");
return 0;
}
关键点:菜单系统需要至少显示一次选项,用户选择“退出”(输入2)时才会终止循环。
5.2 数据库查询的“重试机制”
在读取数据库时,若首次连接失败,可能需要重试:
#include <stdio.h>
int connect_to_database() {
// 模拟数据库连接
static int attempts = 0;
if (attempts < 3) {
attempts++;
return 0; // 连接失败
}
return 1; // 连接成功
}
int main() {
do {
if (connect_to_database()) {
printf("连接成功!\n");
break; // 成功后立即退出循环
}
printf("连接失败,正在重试...\n");
} while (1); // 永真循环,通过 break 控制退出
return 0;
}
技巧:通过 while(1)
创建无限循环,再用 break
语句配合条件判断实现灵活控制。
5.3 游戏中的“回合制”系统
#include <stdio.h>
int main() {
int player_health = 100;
do {
printf("当前血量:%d\n", player_health);
// 模拟玩家操作和敌人攻击
player_health -= 20; // 每回合损失血量
} while (player_health > 0);
printf("游戏结束\n");
return 0;
}
执行结果:即使初始血量为0,循环体仍会执行一次,输出“当前血量:0”,再判断退出。
六、常见问题与调试技巧
6.1 “死循环”陷阱
int count = 0;
do {
printf("%d\n", count);
count += 1;
} while (count < 5); // 正确写法
错误案例:
do {
// ... 省略代码 ...
} while (count = 5); // 赋值操作而非比较!导致死循环
调试方法:
- 检查
while
后的条件表达式是否为逻辑判断(如==
、>
等)。 - 在循环体中打印关键变量的值,确认条件判断的依据是否正确。
6.2 嵌套循环的逻辑控制
int row = 0;
do {
int col = 0;
do {
printf("*");
col++;
} while (col < 5); // 内层循环打印5个星号
printf("\n");
row++;
} while (row < 3); // 外层循环打印3行
输出:
*****
*****
*****
技巧:在嵌套循环中,确保每个循环都有独立的控制变量,避免变量污染。
七、性能与代码规范建议
7.1 执行效率分析
do…while
的执行流程比 while
多一次循环体执行,但这一差异在大多数场景下可以忽略。实际性能更受循环体内代码复杂度影响。
7.2 代码可读性优化
- 单出口原则:尽量让循环只有一个
break
或return
退出点,避免多个出口导致逻辑混乱。 - 条件表达式清晰化:将复杂条件判断提前处理,例如:
do { // ... } while (is_valid() && !exit_flag); // 结合多个条件判断
八、实战案例:猜数字游戏的完整实现
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
srand(time(NULL)); // 初始化随机种子
int secret = rand() % 100 + 1; // 1-100 的随机数
int guess, attempts = 0;
do {
printf("猜一个1-100的数字:");
scanf("%d", &guess);
attempts++;
if (guess < secret) {
printf("太小了!\n");
} else if (guess > secret) {
printf("太大了!\n");
} else {
printf("恭喜!你用了%d次猜中!\n", attempts);
break; // 猜中后退出循环
}
} while (1); // 永真循环,通过 break 控制
return 0;
}
运行示例:
猜一个1-100的数字:50
太大了!
猜一个1-100的数字:25
太小了!
猜一个1-100的数字:37
恭喜!你用了3次猜中!
九、结论:掌握 do…while 的核心价值
通过本文的深入解析,我们明确了 do…while
循环的三个核心价值:
- 强制执行一次:确保关键操作至少运行一次,适用于输入验证、菜单系统等场景。
- 灵活的条件控制:通过
break
和continue
实现复杂逻辑,配合其他循环结构构建高效代码。 - 代码可读性优化:在需要“至少执行一次”的场景中,使用
do…while
能让意图更清晰。
对于编程学习者,建议通过以下步骤掌握这一知识点:
- 模仿练习:将
while
循环的案例改写为do…while
形式,对比差异。 - 实战项目:在自己的项目中寻找需要“至少执行一次”的场景,尝试用
do…while
实现。 - 性能优化:分析循环体内的代码复杂度,通过减少不必要的计算提升效率。
掌握 do…while
循环不仅是语法层面的积累,更是对编程逻辑思维的深化。期待你能在实际开发中灵活运用这一工具,让代码更高效、更优雅!