当前位置: 首页 > news >正文

深入详解C语言的循环结构:while循环、do-while循环、for循环,结合实例,讲透C语言的循环结构


🔥个人主页:艾莉丝努力练剑

❄专栏传送门:《C语言》、《数据结构与算法》、C语言刷题12天IO强训、LeetCode代码强化刷题、C/C++干货分享&学习过程记录

🍉学习方向:C/C++方向

⭐️人生格言:为天地立心,为生民立命,为往圣继绝学,为万世开太平



 C++的两个参考文档:

老朋友(非官方文档):cplusplus

官方文档(同步更新):cppreference


目录

一、C语言的循环结构

(一)while循环

(二)do-while循环

(三)for循环

二、循环的效果

(一)嵌套循环

2.1.1  概念

2.1.2  代码示例

3.1.3  注意

(二)循环控制语句

3.2.1  break语句

3.2.2  continue语句

3.2.3  goto语句(不推荐)

(三)实现无限循环

3.3.1  while实现

3.3.2  for实现

3.3.3  使用场景

三、循环的效率以及三种循环的比较与选择

(一)循环的效率

3.1.1  循环条件

3.1.2  循环展开

3.1.3  减少循环内部计算

(二)三种循环的比较与选择

3.2.1  三种循环的比较

3.2.2  三种循环的选择原则

四、循环的常见问题

五、C语言循环的实际应用场景

(一)示例1:查找素数

(二)示例2:冒泡排序

(三)示例3:用户菜单系统


前言:循环结构是编程中控制程序重复执行某段代码的重要工具。C语言提供了多种循环结构,每种都有其特定的使用场景和特点。下面博主会详细介绍C语言中的几种循环结构。


一、C语言的循环结构

(一)while循环

while (condition) {// 循环体
}

特点:

(1)先判断条件,再决定是否执行循环体;

(2)循环次数不确定,取决于条件;

(3)可能一次都不执行(条件初始为假时)。

代码示例:

int count = 0;
while (count < 5) 
{printf("Count is %d\n", count);count++;
}

应用场景:

(1)当循环次数不确定时;

(2)需要先检查条件再决定是否执行循环时。

(二)do-while循环

do {// 循环体
} while (condition);

特点:

(1)先执行循环体,再判断条件;

(2)至少会执行一次循环体;

(3)条件为真时继续循环。

代码示例:

int num;
do {printf("Enter a positive number: ");scanf("%d", &num);
} while (num <= 0);

应用场景:

(1)需要至少执行一次循环体时;

(2)输入验证等需要先执行再判断的情况。

(三)for循环

这家伙的出场率真是高。

for (initialization; condition; increment/decrement) {// 循环体
}

特点:

(1)结构紧凑,将初始化、条件判断和更新放在一起;

(2)循环次数通常比较明确;

(3)初始化部分只执行一次。

代码示例:

我们就举一个最简单的例子:依次输出0~9——

for (int i = 0; i < 10; i++) 
{printf("%d ", i);
}

应用场景:

(1)循环次数已知或可计算时;

(2)需要同时管理初始化、条件和更新的情况。

二、循环的效果

(一)嵌套循环

2.1.1  概念

嵌套循环:在一个循环体内包含另一个完整的循环结构。

2.1.2  代码示例

下面就是一个嵌套循环的写法——

for (int i = 1; i <= 3; i++) 
{for (int j = 1; j <= 3; j++) {printf("%d * %d = %d\t", i, j, i * j);}printf("\n");
}
3.1.3  注意

(1)内层循环完全执行完毕后,外层循环才会进入下一次迭代;

(2)避免过度嵌套(一般不超过3层),以免降低代码可读性。

(二)循环控制语句

掌握分支循环(二):三种循环、break和continue语句、循环的嵌套以及 goto 语句

3.2.1  break语句

作用:

(1)立即终止当前循环;

(2)用于switch结构或循环结构中。

代码演示:

for (int i = 0; i < 10; i++) 
{if (i == 5) {break;  // 当i等于5时退出循环}printf("%d ", i);
}
3.2.2  continue语句

作用:

(1)跳过当前循环的剩余部分,直接进入下一次循环;

(2)仅用于循环结构中。

代码演示:

for (int i = 0; i < 10; i++) 
{if (i % 2 == 0) {continue;  // 跳过偶数}printf("%d ", i);
}
3.2.3  goto语句(不推荐)

作用:

(1)无条件跳转到指定标签处;

(2)破坏程序结构,应尽量避免使用

话虽如此,goto语句也并不是一无是处——

多层循环的代码中,如果想快速跳出,使用 goto 语句就非常的方便了,比如:

for(...)
{for(...){for(...){if(disaster)goto error;}}
}error://...

上图中的代码中,原本 for 循环想提前退出得使用 break ,一个 break 只能跳出一层 for 循环,如果3层循环嵌套,就得使用3个 break 才能跳出循环,所以在这种情况下我们使用 goto 语句就会更加的快捷。

(三)实现无限循环

3.3.1  while实现
while (1) 
{// 循环体
}
3.3.2  for实现
for (;;) 
{// 循环体
}
3.3.3  使用场景

(1)需要永久运行的循环(如事件循环);

(2)通常配合break语句在特定条件下退出。

三、循环的效率以及三种循环的比较与选择

(一)循环的效率

3.1.1  循环条件

避免在循环条件中使用复杂计算——

好:

int len = strlen(s); for (int i = 0; i < len; i++)

不好:

for (int i = 0; i < strlen(s); i++)
3.1.2  循环展开

减少循环次数以提升性能——

for (int i = 0; i < 100; i += 5) 
{// 处理i// 处理i+1// ...// 处理i+4
}
3.1.3  减少循环内部计算

它会将不变的计算移到循环外部。

(二)三种循环的比较与选择

3.2.1  三种循环的比较

三种循环的比较如下表所示——

循环类型特点适用场景
while先判断,可能不执行循环次数不确定
do-while先执行一次,再判断至少执行一次
for初始化、条件、更新集中管理循环次数已知或可计算
3.2.2  三种循环的选择原则

选择原则:

1、当循环次数已知时,优先使用 for 循环

2、当循环至少要执行一次时,考虑 do - while 循环

3、其他情况使用 while 循环

时间复杂度的问题前面博主已经详细介绍过了,这里不再赘述,大家可以去看这篇文章——

【数据结构】详解算法复杂度:时间复杂度和空间复杂度

对于时间复杂度和空间复杂度的知识点介绍得还是非常详细的。

四、循环的常见问题

4.1  无限循环问题:忘记更新循环变量——

int i = 0;
while (i < 10) 
{printf("%d ", i);// 忘记i++
}

4.2  分号问题:循环体后误加分号——非常常见的一个问题——

for (int i = 0; i < 10; i++);  // 这个分号会导致循环体为空
{printf("%d ", i);
}

4.3  浮点数比较问题:使用浮点数作为循环变量可能导致精度问题——

for (float f = 0.0; f != 1.0; f += 0.1) 
{printf("%f ", f);
}

不推荐用浮点数作为循环变量。

4.4  修改循环变量问题:在循环体内修改循环变量可能导致意外行为——

for (int i = 0; i < 10; i++) 
{if (i == 5) {i = 8;  // 直接跳转}printf("%d ", i);
}

在循环体内修改循环变量可能会导致直接跳转的问题产生。

五、C语言循环的实际应用场景

这里我们直接展示代码,就不展开具体说明了。

(一)示例1:查找素数

#include <stdio.h>
#include <stdbool.h>bool is_prime(int n) 
{if (n <= 1) return false;for (int i = 2; i * i <= n; i++) {if (n % i == 0) return false;}return true;
}int main() 
{int limit = 100;printf("Prime numbers up to %d:\n", limit);for (int num = 2; num <= limit; num++) {if (is_prime(num)) {printf("%d ", num);}}return 0;
}

(二)示例2:冒泡排序

void bubble_sort(int arr[], int size) 
{for (int i = 0; i < size - 1; i++) {for (int j = 0; j < size - i - 1; j++) {if (arr[j] > arr[j + 1]) {// 交换int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
}

(三)示例3:用户菜单系统

#include <stdio.h>int main() 
{int choice;do {printf("\nMenu:\n");printf("1. Option 1\n");printf("2. Option 2\n");printf("3. Exit\n");printf("Enter your choice: ");scanf("%d", &choice);switch (choice) {case 1:printf("You selected Option 1\n");break;case 2:printf("You selected Option 2\n");break;case 3:printf("Exiting...\n");break;default:printf("Invalid choice. Try again.\n");}} while (choice != 3);return 0;
}

总结:

(1)while 循环适用于循环次数不确定的情况;

(2)do - while 循环适用于至少需要执行一次的情况;

(3)for 循环适用于循环次数已知的情况;

(4)嵌套循环可以处理多维数据或多重条件;

(5)控制语句里的 breakcontinue 可以更灵活地控制循环流程。

往期回顾:

【C/C++】详解内存对齐问题,C语言内存对齐整理

结语:本文内容到这里就结束了,大家不要忘了给博主“一键四连”哦!

http://www.dtcms.com/a/330324.html

相关文章:

  • 关于linux软件编程4:目录IO和一些时间函数
  • PAT 1065 A+B and C (64bit)
  • 驱动开发系列62 - glBufferDataARB实现分析
  • Windows下cuda的安装和配置
  • BGP 笔记梳理
  • 110. 字符串接龙
  • 【Spring AI 1.0.0】Spring AI 1.0.0框架快速入门(6)——MCP Client(MCP客户端)
  • 最新Coze(扣子)智能体工作流:用Coze实现「图片生成-视频制作」全自动化,3分钟批量产出爆款内容
  • Docker网络命名空间隔离与VPS服务器环境的连通性测试方法解析
  • kali linux 2025.2配置局域网打印服务器惠普打印机HP1108p
  • MySQL查询表结构、表大小
  • 告别意外中断,iOS辅助工具按键精灵「异常停止重启脚本」功能介绍
  • <c1:C1DateTimePicker的日期时间控件,控制日期可以修改,时间不能修改,另外控制开始时间的最大值比结束时间小一天
  • git clone 支持在命令行临时设置proxy
  • 康托展开与逆康托展开
  • 词向量转化
  • RocketMQ 消息存储机制 CommitLog和ConsumerQu
  • 第八课:python的运算符
  • 从 VLA 到 VLM:低延迟RTSP|RTMP视频链路在多模态AI中的核心角色与工程实现
  • 论文分享 | Flashboom:一种声东击西攻击手段以致盲基于大语言模型的代码审计
  • 04-spring-手写spring-demo-aop0V1
  • Canal解析MySQL Binlog原理与应用
  • Unity、C#常用的时间处理类
  • Laravel 使用ssh链接远程数据库
  • 使用 Simple Floating Menu 插件轻松实现浮动联系表单
  • AI一周事件(2025年8月6日-8月12日)
  • [ Mybatis 多表关联查询 ] resultMap
  • ResourcelessTransactionManager的作用
  • 第三天-如何在DBC中描述CAN Signal的“负数/值”
  • JetPack系列教程(六):Paging——让分页加载不再“秃”然