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

C语言速成之08循环语句全解析:从基础用法到高效实践

C语言循环语句全解析:从基础用法到高效实践

大家好,我是Feri,12年+开发经验的程序员。循环语句是程序实现重复逻辑的核心工具,掌握whiledo-whilefor的特性与适用场景,能让代码更简洁高效。本文结合实战案例,带你深入理解C语言循环体系。

一、循环语句:重复逻辑的引擎

在C语言中,循环语句通过条件控制代码块的重复执行,是构建算法和处理批量数据的基础。三大核心循环类型:

  • while:先判断后执行,适用于条件驱动的不确定次数循环

  • do-while:先执行后判断,确保循环体至少执行一次

  • for:初始化、条件、更新一体化,适合已知次数的循环

二、三大循环深度解析

2.1 while循环:条件优先的"预判断"循环

语法结构

while (条件表达式) {  循环体;  // 条件为真时重复执行  
}  

执行逻辑

  1. 计算条件表达式,非零则执行循环体

  2. 循环体执行完毕后,再次判断条件,直至条件为零终止

典型场景:处理不确定次数的循环(如用户输入验证)

// 输入1-100的整数,错误时重复提示  
void input_validation() {  int num;  while (1) {  // 无限循环,需内部条件break  printf("请输入1-100的整数:");  scanf("%d", &num);  if (num >= 1 && num <= 100) {  break;  // 满足条件时终止循环  }  printf("输入错误,请重新输入!\n");  }  
}  

注意:循环体内必须包含修改条件表达式的语句,避免死循环。

2.2 do-while循环:至少执行一次的"后判断"循环

语法结构

do {  循环体;  // 先执行一次,再判断条件  
} while (条件表达式);  // 末尾分号不可省略  

执行逻辑

  1. 无条件执行一次循环体

  2. 计算条件表达式,非零则重复执行循环体

典型场景:至少需要一次交互的场景(如命令行菜单)

// 简易菜单系统,至少显示一次选项  
void menu_system() {  int choice;  do {  printf("1. 查看数据  2. 退出程序\n");  scanf("%d", &choice);  switch (choice) {  case 1: printf("数据查看功能\n"); break;  case 2: printf("退出程序\n"); break;  default: printf("无效选择,请重新输入\n");  }  } while (choice != 2);  // 输入2时退出  
}  

核心优势:确保循环体至少执行一次,避免条件不满足时直接跳过。

2.3 for循环:结构化的"计数型"循环

语法结构

for (初始化; 条件表达式; 更新表达式) {  循环体;  // 条件为真时执行  
}  

执行顺序

  1. 执行初始化(仅一次)

  2. 判断条件,非零则执行循环体

  3. 执行更新表达式,重复步骤2

典型场景:已知次数的循环(如数组遍历、数学迭代)

// 计算1-100累加和(传统写法)  
int sum_traditional() {  int sum = 0;  for (int i = 1; i <= 100; i++) {  sum += i;  }  return sum;  
}  // 增强写法:省略部分表达式(无限循环需内部break)  
int sum_advanced() {  int sum = 0, i = 1;  for (; i <= 100;) {  // 省略初始化和更新表达式  sum += i++;  // 合并更新操作  }  return sum;  
}  

语法糖技巧

  • 初始化表达式可声明多个变量:for (int i=0, j=10; i<j; i++, j--)

  • 条件表达式可省略(默认为真,需内部break终止)

三、循环控制语句:精准操纵循环流程

3.1 break:终止当前循环

  • 作用:跳出所在的最内层循环,执行后续代码

  • 场景:满足特定条件时提前终止(如找到目标元素)

// 在数组中查找第一个负数,找到后终止循环  
int find_negative(int arr[], int len) {  for (int i=0; i<len; i++) {  if (arr[i] < 0) {  printf("第一个负数在索引%d\n", i);  break;  // 立即跳出for循环  }  }  
}  

3.2 continue:跳过本次循环剩余代码

  • 作用:终止当前循环迭代,直接进入下一次条件判断

  • 场景:忽略不符合条件的迭代(如过滤无效数据)

// 打印1-10中的非3的倍数  
void print_non_multiple() {  for (int i=1; i<=10; i++) {  if (i % 3 == 0) {  continue;  // 跳过3的倍数,不执行后续printf  }  printf("%d ", i);  // 输出1 2 4 5 7 8 10  }  
}  

3.3 嵌套循环中的控制

  • 多层break:需跳出外层循环时,可使用标记跳转(谨慎使用)
    outer_loop:  
    for (int i=0; i<5; i++) {  for (int j=0; j<5; j++) {  if (i + j == 5) {  break outer_loop;  // 跳出外层for循环  }  }  
    }  
    
  • 最佳实践:嵌套深度不超过3层,复杂逻辑拆分为独立函数

四、三大循环对比与选型指南

特性whiledo-whilefor
执行顺序先判断,后执行先执行,后判断先初始化,再判断执行
循环体执行次数0次或多次至少1次0次或多次
适用场景条件驱动的不确定循环至少一次执行的场景已知次数的计数循环
语法结构简洁的条件前置强制首次执行初始化/条件/更新一体化

选型建议

  • 明确循环次数:优先for(结构清晰,便于调试)

  • 条件不确定:使用while(如文件读取while (!feof(fp))

  • 至少执行一次:选择do-while(如用户输入校验)

五、高效循环编程技巧

  1. 减少循环体内计算:将不变的表达式移到循环外

    // 反例:重复计算数组长度  
    for (int i=0; i<sizeof(arr)/sizeof(arr[0]); i++) {...}  // 正例:提前计算长度  
    int len = sizeof(arr)/sizeof(arr[0]);  
    for (int i=0; i<len; i++) {...}  
    
  2. 逆向循环优化:某些场景下从后往前更高效(如数组去重)

    // 删除数组中的指定元素(逆向遍历避免索引混乱)  
    for (int i=len-1; i>=0; i--) {  if (arr[i] == target) {  // 移除元素操作  }  
    }  
    
  3. 循环展开:牺牲代码体积换取执行速度(需谨慎使用)

    // 展开4次循环,减少条件判断次数  
    for (int i=0; i<len; i+=4) {  process(arr[i]);  process(arr[i+1]);  process(arr[i+2]);  process(arr[i+3]);  
    }  
    

六、常见错误与避坑指南

错误类型示例代码解决方案
死循环while (1);(无break)添加终止条件或break语句
循环变量未初始化for (int i=0; i<10; ) {i++;}确保初始化表达式正确设置变量
break误用在switch中使用break终止外层循环使用标记或重构代码结构
嵌套循环性能问题多层循环中重复计算复杂表达式预计算中间值或提取公共逻辑

总结:循环语句的核心价值

循环语句是算法实现的基石,掌握其特性可显著提升代码质量:

  • while:灵活应对条件驱动的动态循环

  • do-while:保障关键逻辑至少执行一次

  • for:高效处理计数型循环,结构紧凑易维护

  • 控制语句:通过break/continue精准控制流程

在实际开发中,应根据场景选择合适的循环类型,遵循"清晰优先、性能次之"的原则,避免过度优化。下一篇我们将深入探讨数组与指针的核心用法,敬请期待!

关注我,一起掌握嵌入式开发核心技能,让每一行循环代码都高效且健壮!

相关文章:

C语言速成之08循环语句全解析:从基础用法到高效实践

C语言循环语句全解析&#xff1a;从基础用法到高效实践 大家好&#xff0c;我是Feri&#xff0c;12年开发经验的程序员。循环语句是程序实现重复逻辑的核心工具&#xff0c;掌握while、do-while、for的特性与适用场景&#xff0c;能让代码更简洁高效。本文结合实战案例&#xf…...

多模态大语言模型arxiv论文略读(六十九)

Prompt-Aware Adapter: Towards Learning Adaptive Visual Tokens for Multimodal Large Language Models ➡️ 论文标题&#xff1a;Prompt-Aware Adapter: Towards Learning Adaptive Visual Tokens for Multimodal Large Language Models ➡️ 论文作者&#xff1a;Yue Zha…...

云计算-容器云-部署CICD-jenkins连接gitlab

安装 Jenkins 将Jenkins部署到default命名空间下。要求完成离线插件的安装,设置Jenkins的登录信息和授权策略。 上传BlueOcean.tar.gz包 [root@k8s-master-node1 ~]#tar -zxvf BlueOcean.tar.gz [root@k8s-master-node1 ~]#cd BlueOcean/images/ vim /etc/docker/daemon.json…...

精讲C++四大核心特性:内联函数加速原理、auto智能推导、范围for循环与空指针进阶

前引&#xff1a;在C语言长达三十余年的演进历程中&#xff0c;每一次标准更新都在试图平衡性能与抽象、控制与安全之间的微妙关系。从C11引入的"现代C"范式开始&#xff0c;开发者得以在保留底层控制能力的同时&#xff0c;借助语言特性大幅提升代码的可维护性与安全…...

【HarmonyOS 5】鸿蒙中常见的标题栏布局方案

【HarmonyOS 5】鸿蒙中常见的标题栏布局方案 一、问题背景&#xff1a; 鸿蒙中常见的标题栏&#xff1a;矩形区域&#xff0c;左边是返回按钮&#xff0c;右边是问号帮助按钮&#xff0c;中间是标题文字。 那有几种布局方式&#xff0c;分别怎么布局呢&#xff1f;常见的思维…...

Docker 部署 - Crawl4AI 文档 (v0.5.x)

Docker 部署 - Crawl4AI 文档 (v0.5.x) 快速入门 &#x1f680; 拉取并运行基础版本&#xff1a; # 不带安全性的基本运行 docker pull unclecode/crawl4ai:basic docker run -p 11235:11235 unclecode/crawl4ai:basic# 带有 API 安全性启用的运行 docker run -p 11235:1123…...

QuecPython+Aws:快速连接亚马逊 IoT 平台

提供一个可接入亚马逊 Iot 平台的客户端&#xff0c;用于管理亚马逊 MQTT 连接和影子设备。 初始化客户端 Aws class Aws(client_id,server,port,keep_alive,ssl,ssl_params)参数&#xff1a; client_id (str) - 客户端唯一标识。server (str) - 亚马逊 Iot 平台服务器地址…...

内存安全暗战:从 CVE-2025-21298 看 C 语言防御体系的范式革命

引言 2025 年 3 月&#xff0c;当某工业控制软件因 CVE-2025-21298 漏洞遭攻击&#xff0c;导致欧洲某能源枢纽的电力调度系统瘫痪 37 分钟时&#xff0c;全球网络安全社区再次被拉回 C 语言内存安全的核心战场。根据 CISA 年度报告&#xff0c;68% 的高危漏洞源于 C/C 代码&a…...

SpringCloud Gateway知识点整理和全局过滤器实现

predicate(断言)&#xff1a; 判断uri是否符合规则 • 最常用的的就是PathPredicate&#xff0c;以下列子就是只有url中有user前缀的才能被gateway识别&#xff0c;否则它不会进行路由转发 routes:- id: ***# uri: lb://starry-sky-upmsuri: http://localhost:9003/predicate…...

全球实物文件粉碎服务市场洞察:合规驱动下的安全经济与绿色转型

一、引言&#xff1a;从纸质堆叠到数据安全的“最后一公里” 在数字化转型浪潮中&#xff0c;全球企业每年仍产生超过1.2万亿页纸质文件&#xff0c;其中包含大量机密数据、客户隐私及商业敏感信息。据QYResearch预测&#xff0c;2031年全球实物文件粉碎服务市场规模将达290.4…...

冒泡排序的原理

冒泡排序是一种简单的排序算法&#xff0c;它通过重复地遍历待排序的列表&#xff0c;比较相邻的元素并交换它们的位置来实现排序。具体原理如下&#xff1a; 冒泡排序的基本思想 冒泡排序的核心思想是通过相邻元素的比较和交换&#xff0c;将较大的元素逐步“冒泡”到列表的…...

Day22 Kaggle泰坦尼克号训练实战

​ 作业 自行学习参考如何使用kaggle平台&#xff0c;写下使用注意点&#xff0c;并对下述比赛提交代码 kaggle泰坦里克号人员生还预测 一、流程 思路概述 数据加载 &#xff1a;读取泰坦尼克号的训练集和测试集。数据预处理 &#xff1a;处理缺失值、对分类变量进行编码、…...

深入浅出之STL源码分析7_模版实例化与全特化

1.引言 显示实例话和全特化的区别&#xff0c;之前我们在讨论类模版的时候&#xff0c;讨论过&#xff0c;他俩不是同一个概念&#xff0c;类模版中你如果全特化了&#xff0c;还是需要实例化才能生成代码&#xff0c;但是对于函数模版&#xff0c;这个是不同的&#xff0c;函…...

CAPL -实现SPRMIB功能验证

系列文章目录 抑制肯定响应消息指示位&#xff08;SPRMIB&#xff09; 二十一、CANdelaStudio深入-SPRMIB的配置 文章目录 系列文章目录一、SPRMIB是什么&#xff1f;二、SetSuppressResp(long flag)三、GetSuppressResp 一、SPRMIB是什么&#xff1f; 正响应&#xff1a;表示…...

2025 Mac常用软件安装配置

1、homebrew 2、jdk 1、使用brew安装jdk&#xff1a; brew install adoptopenjdk/openjdk/adoptopenjdk8 jdk默认安装位置在 /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home 目录。 2、配置环境变量&#xff1a; vim ~/.zshrc# Jdk export JAVA_HOM…...

容器技术 20 年:颠覆、重构与重塑软件世界的力量

目录 容器技术发展史 虚拟化技术向容器技术转变 Docker的横空出世 容器编排技术与Kubernetes 微服务的出现与Istio 工业标准的容器运行时 容器技术与 DevOps 的深度融合​ 无服务架构推波助澜 展望未来发展方向 从 20 世纪硬件虚拟化的笨重&#xff0c;到操作系统虚拟…...

cmake:test project

本文主要探讨cmake在测试和项目中的应用。 add_test add_test(NAME <name> COMMAND <command> [<arg>...] [CONFIGURATIONS <config>...] [WORKING_DIRECTORY <dir>] [COMMAND_EXPAND_LISTS])  add_test(NAME test_uni COMMAND $<TARGET_F…...

C++开发过程中的注意事项详解

目录 C++开发过程中的注意事项详解 一、内存管理:避免泄漏与资源浪费 1.1 使用智能指针管理动态内存 1.2 避免手动内存管理的陷阱 1.3 利用RAII机制管理资源 1.4 容器与内存分配 二、安全性:防御攻击与未定义行为 2.1 输入验证与安全编码 2.2 使用安全的通信协议 2…...

OpenWrt开发第8篇:树莓派开发板做无线接入点

文/指尖动听知识库-谷谷 文章为付费内容,商业行为,禁止私自转载及抄袭,违者必究!!! 文章专栏:Openwrt开发-基于Raspberry Pi 4B开发板 树莓派开发板作为无线接入点的时候,可以通过电脑和手机打开WiFi功能搜索到相应打开的WiFi; 1 通过Web操作界面开启wifi 1...

Leetcode (力扣)做题记录 hot100(42,104,226,101)

力扣第42题&#xff1a;接雨水 42. 接雨水 - 力扣&#xff08;LeetCode&#xff09; 左边遍历一次记录左侧最大值 右边同理&#xff0c;最后遍历一次 左侧右侧最小值减去当前值即可。 class Solution {public int trap(int[] height) {int n height.length;int[] leftMax …...

第六天:Java数组

数组 数组概述 数组是相同类型数据的有序集合。数组中的元素可以是任意数据类型&#xff0c;包括基本类型和引用类型数组描述是相同类型的若干个数据&#xff0c;按照一定的先后顺序排列组合而成。数组下标从0开始。 数组声明与创建 数组的声明 int[] nums;//声明一个数组…...

李沐动手深度学习(pycharm中运行笔记)——09.softmax回归+图像分类数据集+从零实现+简洁实现

09.softmax回归图像分类数据集从零实现简洁实现&#xff08;与课程对应&#xff09; 目录 一、softmax回归 1、回归 vs 分类 2、经典分类数据集&#xff1a; 3、从回归到分类——均方损失 4、从回归到多类分类——无校验比例 5、从回归到多类分类——校验比例 6、softmax和…...

Kubernetes生产实战(二十):容器大镜像拉取优化指南

在 Kubernetes 中优化大容器镜像的拉取速度&#xff0c;需要结合 镜像构建策略、集群网络架构 和 运行时配置 多方面进行优化。以下是分步解决方案&#xff1a; 一、镜像构建优化&#xff1a;减小镜像体积 1. 使用轻量级基础镜像 替换 ubuntu、centos 为 alpine、distroless …...

Qt获取CPU使用率及内存占用大小

Qt 获取 CPU 使用率及内存占用大小 文章目录 Qt 获取 CPU 使用率及内存占用大小一、简介二、关键函数2.1 获取当前运行程序pid2.2 通过pid获取运行时间2.3 通过pid获取内存大小 三、具体实现五、写在最后 ​ 一、简介 近期在使用软件的过程中发现一个有意思的东西。如下所示&a…...

8. HTML 表单基础

表单是网页开发中与用户交互的核心组件,用于收集、验证和提交用户输入的数据。本文将基于提供的代码素材,系统讲解 HTML 表单的核心概念、常用控件及最佳实践。 一、表单的基本结构 一个完整的 HTML 表单由以下部分组成: <form action="/submit" method=&quo…...

嵌入式学习笔记 - 运算放大器的共模抑制比

一 定义 共模抑制比&#xff08;Common Mode Rejection Ratio, ‌CMRR‌&#xff09;是衡量差分放大器&#xff08;或差分电路&#xff09;抑制共模信号能力的关键指标。它在电子工程中尤为重要&#xff0c;特别是在需要处理微弱信号或对抗环境噪声的场景中。 核心概念 ‌共…...

《Go小技巧易错点100例》第三十三篇

​ Validator自定义校验规则 Go语言中广泛使用的validator库支持通过结构体标签定义校验规则。当内置规则无法满足需求时&#xff0c;我们可以轻松扩展自定义校验逻辑。 示例场景&#xff1a;验证用户年龄是否成年&#xff08;≥18岁&#xff09; type User struct {Age in…...

牛客周赛 Round 92-题解

牛客周赛 Round 92-题解 A-小红的签到题 code #include<iostream> #include<string> using namespace std; string s; int main() {int n;cin >> n;cout << "a_";for (int i 0; i < n - 2; i )cout << b;return 0; }B-小红的模…...

【PVE】ProxmoxVE8虚拟机,存储管理(host磁盘扩容,qcow2/vmdk导入vm,vm磁盘导出与迁移等)

【PVE】ProxmoxVE8虚拟机&#xff0c;存储管理&#xff08;host磁盘扩容&#xff0c;qcow2/vmdk导入vm&#xff0c;vm磁盘导出与迁移等&#xff09; 文章目录 1、host 磁盘扩容2、qcow2/vmdk导入vm3、vm 磁盘导出与迁移 1、host 磁盘扩容 如何给host扩容磁盘&#xff0c;如增加…...

Umi+React+Xrender+Hsf项目开发总结

一、菜单路由配置 1.umirc.ts 中的路由配置 .umirc.ts 文件是 UmiJS 框架中的一个配置文件&#xff0c;用于配置应用的全局设置&#xff0c;包括但不限于路由、插件、样式等。 import { defineConfig } from umi; import config from ./def/config;export default defineCon…...