C语言 do...while、循环控制及goto语句详解与实战
do...while 循环是 C 语言中唯一一种至少执行一次循环体的结构。本文将讲解其语法、执行流程,重点分析 break 和 continue 在其中的行为差异(特别是 continue 易导致的死循环),并通过阶乘、二分查找等经典练习掌握循环逻辑,最后介绍 goto 语句的特定用途。
do...while 循环的核心逻辑
第1步:掌握 do...while 的基本语法
do...while 循环的特点是先执行循环体,再判断条件。只要条件为真(非0),就继续执行;否则退出循环。其标准语法结构如下:
do {
循环语句;
} while(表达式);
注意: while(表达式) 后面必须加分号 ;,这是新手常犯的错误。
第2步:理解执行流程与适用场景
由于先执行后判断,do...while 循环体内的代码至少会执行一次。这一特性使其非常适合用于“无论结果如何,至少执行一次”的场景,例如菜单选择界面、游戏开始界面或用户登录验证。
基本示例:展示即使初始条件不满足,循环体仍执行一次的情况。
#include <stdio.h>
int main()
{
int i = 10;
do
{
printf("%d\n", i);
} while (i < 10); // 初始 i=10,条件 i<10 为假,但上面仍打印了一次 10
return 0;
}
第3步:区分 break 与 continue 的行为
在 do...while 中,break 和 continue 的行为与其他循环类似但有细微差别,需特别注意 continue 可能引发的死循环。
1. break 语句:
作用是完全终止并跳出当前所在的整个循环层。当执行到 break 时,程序直接跳到循环体结束后的下一条语句。
#include <stdio.h>
int main()
{
int i = 0;
do
{
if (5 == i)
break; // 当 i 为 5 时跳出循环
printf("%d\n", i);
i++;
} while (i < 10);
return 0;
}
// 输出结果: 0 1 2 3 4
2. continue 语句:
作用是跳过本次循环中剩余的代码,直接进入 while(表达式) 的条件判断。
⚠️ 高风险提示: 如果在 i++ 之前使用了 continue,且变量 i 没有在其他地方递增,条件判断可能会一直成立,导致死循环。
#include <stdio.h>
int main()
{
int i = 0;
do
{
if (5 == i)
continue; // 跳到 while(i<10),此时 i 仍为 5,条件永远成立!
printf("%d\n", i);
i++; // i++ 被跳过,i 永远无法大于等于 5
} while (i < 10);
return 0;
}
循环综合实战练习
通过以下经典题目,将分支结构与循环结合使用,巩固编程思维。
第1步:计算阶乘及其累加和
任务A: 计算 n 的阶乘。利用 for 循环从 1 乘到 n。
#include <stdio.h>
int main()
{
int n = 0;
int ret = 1; // 结果变量初始化
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
ret *= i;
}
printf("%d", ret);
return 0;
}
任务B: 计算 1! + 2! + ... + 10!。关键在于维护一个中间结果 ret 存储当前的阶乘值,每次迭代更新后加到总和 sum 中。
#include <stdio.h>
int main()
{
int sum = 0;
int ret = 1; // 注意:如果外层用两个for循环,内层必须重置ret=1
for (int i = 1; i <= 10; i++)
{
ret *= i; // 累乘得到 i!
sum += ret; // 累加到总和中
}
printf("%d", sum);
return 0;
}
第2步:有序数组查找(二分法)
在有序数组中快速定位目标,核心思想是不断缩小搜索范围。定义左边界 left、右边界 right 和中间值 mid。
#include <stdio.h>
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int left = 0;
int right = sizeof(arr) / sizeof(arr[0]) - 1;
int key = 7;
int mid = 0;
while (left <= right) // 关键终止条件
{
mid = (left + right) / 2;
if (arr[mid] > key)
{
right = mid - 1; // 目标在左边,收缩右边界
}
else if (arr[mid] < key)
{
left = mid + 1; // 目标在右边,收缩左边界
}
else
{
break; // 找到目标
}
}
if (left <= right)
printf("找到了,下标是%d\n", mid);
else
printf("找不到\n");
return 0;
}
第3步:模拟用户登录验证
限制尝试次数(如3次),并使用字符串比较函数 strcmp 进行密码比对。字符串不能直接用 == 比较。
#include <stdio.h>
#include <string.h>
int main()
{
char psw[10] = "";
int attempts = 0;
for (attempts = 0; attempts < 3; ++attempts)
{
printf("请输入密码: ");
scanf("%s", psw);
if (strcmp(psw, "password") == 0)
{
break; // 密码正确,跳出循环
}
}
if (attempts == 3)
printf("次数耗尽,程序退出\n");
else
printf("登录成功\n");
return 0;
}
第4步:完整项目 - 猜数字游戏
这是一个综合性小项目,结合了函数模块化、随机数生成 (rand(), srand())、switch-case 分支以及 do...while 菜单循环。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void menu() {
printf("**************************\n");
printf("******* 1. Play *********\n");
printf("******* 0. Exit *********\n");
printf("**************************\n");
}
void game() {
int random_num = rand() % 100 + 1;
int input = 0;
while (1) {
printf("请输入猜测的数字 >: ");
scanf("%d", &input);
if (input > random_num)
printf("猜大了\n");
else if (input < random_num)
printf("猜小了\n");
else {
printf("恭喜你,猜对了!\n");
break;
}
}
}
int main() {
int input = 0;
srand((unsigned int)time(NULL)); // 初始化随机数种子,只需调用一次
do {
menu();
printf("请选择 >:");
scanf("%d", &input);
switch (input) {
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入!\n");
break;
}
} while (input); // input != 0 则继续循环
return 0;
}
关于 goto 语句的特殊用途
C语言提供 goto 语句用于无条件跳转至标记位置。虽然一般不建议随意使用,但在处理深层嵌套循环错误或资源释放时,它比多层 break 更清晰简洁。
典型场景: 一次性跳出两层或多层循环或处理复杂错误路径。
// 错误处理示例
for (...)
{
for (...)
{
if (disaster)
goto error; // 直接跳到底部错误处理区
}
}
error:
// 清理资源...
return -1;
注意: 除非确实能简化复杂逻辑(如多层嵌套的退出),否则应优先使用结构化控制语句(如 while 配合标志位),以保持代码的可读性和可维护性。
以上就是C语言 do...while 循环、循环控制符及 goto 语句的详细内容,更多关于 C语言基础教程的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









