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

c语言知识总结(3.控制结构)

一、条件语句:

1. if与else的运用

if:条件为真(非0)时执行

if (条件) { // 成立时执行 }

if-else:二选一

if (条件) { // 成立时执行 } else { // 不成立时执行 }

多分支:多选一,从上到下匹配,遇到第一个真条件执行后结束

if (条件1) { // 条件1成立 } else if (条件2) { // 条件1不成立且条件2成立 } else { // 全都不成立 }

嵌套:if 里再放 if

if (条件1) { if (条件2) { // 条件1和条件2都成立 } }

常见错误与规则

错误/规则说明示例
忘加 {}if 默认只管一条语句,多条必须加{}if (x>0) a++; b++;b 不在 if 内
= 和 ==if (x = 1)是赋值,恒真if (x == 1)才是判断
else 匹配规则else 与最近未配对的 if 配对见下方示例
else 单独使用else 不能脱离 if 存在else { ... }
中间多写语句if 和 else 之间不能有其他语句if (x>0) a++; b++; else ...
条件顺序多分支时范围大的放前面或后面if (>=60) 不及格顺序错误

else 匹配规则示例

if (a > 0) if (b > 0) printf("a和b都大于0"); else printf("a不大于0"); // 这个 else 匹配的是内层 if(b>0)! //解决:用 {} 明确范围 if (a > 0) { if (b > 0) { printf("a和b都大于0"); } } else { printf("a不大于0"); // 明确匹配外层 if }

2.switch的使用

2.1基本用法


switch 用于多分支等值判断,根据表达式的值跳转到对应的 case 执行。

switch (整型表达式) { case 常量1: // 表达式 == 常量1 时执行 break; // 跳出 switch case 常量2: // 表达式 == 常量2 时执行 break; default: // 以上都不匹配时执行 }
  • 表达式必须是整型(int、char、enum)
  • case 后面必须是常量

  • 从上到下匹配,找到相等的 case 后执行该 case 及后面所有语句(直到遇到 break 或 switch 结束)

  • break用于跳出 switch,防止穿透

  • default处理所有未匹配的情况(可省略)

int week = 3; switch (week) { case 1: printf("星期一\n"); break; case 2: printf("星期二\n"); break; case 3: printf("星期三\n"); break; case 4: printf("星期四\n"); break; default: printf("输入错误\n"); } // 输出:星期三
int n = 2; switch (n) { case 1: printf("一"); case 2: printf("二"); // 执行这里 case 3: printf("三"); // 穿透继续执行 } // 输出:二三

2.2穿透性质的应用

场景示例
成绩分组90-100分、80-89分 归为同一档
月份天数1、3、5、7、8、10、12月都是31天
字符分类元音字母、数字字符、空格符等
状态机多个状态触发同一动作
int month = 7; int days; switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: days = 31; // 这些月份都是31天 break; case 4: case 6: case 9: case 11: days = 30; // 这些月份都是30天 break; case 2: days = 28; // 2月单独处理 break; }

二、循环语句

1.for循环

1.1 基本语法

for (初始化表达式; 循环条件; 循环更新) { // 循环体语句 }
部分作用执行时机
初始化定义循环变量,赋初值循环开始前执行一次
循环条件判断是否继续循环每次循环开始前判断
循环更新改变循环变量每次循环体执行完后执行
循环体要重复执行的代码条件为真时执行

基本示例:输出 1 到 5

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

1.2 使用建议

建议说明
循环变量用 i、j、k约定俗成,清晰明了
不要修改循环变量容易造成混乱或无限循环
循环体内加{}即使只有一条语句
避免太深的嵌套超过三层考虑重构
循环变量作用域最小化C99 后可在 for 内定义循环变量

2.while循环

2.1 基本语法

while 循环用于未知循环次数,根据条件决定是否继续循环。

while (循环条件) { // 循环体语句 }
部分作用执行时机
循环条件判断是否继续循环每次循环开始前判断
循环体要重复执行的代码条件为真时执行

基本示例:输出 1 到 5

int i = 1; while (i <= 5) { printf("%d ", i); i++; }

2.2使用建议

建议说明
确保循环变量更新避免无限循环
循环体内加{}即使只有一条语句
避免用赋值当条件while (i = 5)是常见错误
注意 continue 位置确保循环变量能更新

3.do-while循环

3.1 基本语法

do-while 循环与 while 类似,但先执行一次循环体,再判断条件

do { // 循环体语句 } while (循环条件); // 注意这里有分号!
部分作用执行时机
循环体要重复执行的代码至少执行一次
循环条件判断是否继续循环每次循环体执行完后判断

3.2 do-while 与 while 的对比

对比do-whilewhile
执行顺序先执行后判断先判断后执行
最少执行次数1 次(至少执行一次)0 次(可能一次都不执行)
适用场景至少需要执行一次可能一次都不执行
语法结尾有分号 !!!结尾无分号

对比示例:条件一开始为假

// do-while:至少执行一次 int i = 10; do { printf("至少执行一次\n"); // 会执行 } while (i < 5); // while:一次都不执行 int i = 10; while (i < 5) { printf("不会执行\n"); // 不执行 }

4.嵌套循环

嵌套循环指一个循环语句内部再包含另一个完整的循环语句。外层循环执行一次,内层循环执行完整一轮。

4.1嵌套意义

外层循环控制“行”,内层循环控制“列”——嵌套循环用来处理二维结构重复做某件事多次

三大典型应用场景

场景意义示例
处理二维数据访问矩阵、表格、图像像素遍历二维数组、矩阵运算
打印图形控制行和列的数量关系矩形、三角形、菱形
重复执行某件事多次对每个外层元素,内层做固定操作排序算法、穷举搜索

4.2执行次数计算

循环结构执行次数示例
单层循环n1 到 n
双层循环n × m3 × 4 = 12 次
三层循环n × m × k2 × 3 × 4 = 24 次

4.3常见错误

1:内外层使用相同循环变量

for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) { // 内层同名变量 printf("%d ", i); } }

2:忘记初始化内层变量

int j = 0; while (j < 3) { printf("%d ", j); j++; } // 输出:0 1 2 int i = 0; while (i < 2) { while (j < 3) { // ❌ j 已经是 3,内层一次都不执行 printf("(%d,%d)", i, j); j++; } i++; } // 输出:(空)

3:花括号缺失

for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) printf("(%d,%d) ", i, j); printf("\n"); // 这行不在内层循环后

5.循环常见错误

循环通用陷阱

陷阱说明错误示例
忘记加 {}循环默认只管一条语句while (i<5) a++; b++;b不在循环内
分号放错)后面直接加分号,循环体为空for (i=0; i<5; i++);
赋值当条件=写成==,条件恒真while (i = 5)无限循环
条件写反循环条件逻辑错误for (i=5; i>0; i++)越来越大
忘记更新变量循环变量不更新,死循环while (i<5) { printf("%d", i); }忘写 i++

各循环独有的坑

循环独有陷阱说明示例
for分号放错位置for (...);循环体为空for (i=0; i<5; i++); { printf("%d", i); }
whilecontinue跳过更新continue 可能导致循环变量更新被跳过while (i<5) { if (i==3) continue; i++; }
do-while末尾忘记分号} while (条件)后面必须有;do { ... } while (条件)编译错误

6.三种循环对比*

对比项for 循环while 循环do-while 循环
语法for (初始化; 条件; 更新) {}while (条件) {}do {} while (条件);
执行顺序先判断后执行先判断后执行先执行后判断
最少执行次数0 次0 次1 次
适用场景已知循环次数未知次数,条件控制至少执行一次
初始化位置在 for 头部循环外定义循环外定义
更新位置在 for 头部循环体内手动循环体内手动
无限循环for (;;)while (1)do {} while (1);
结尾分号必须有;
场景推荐循环原因
已知循环次数for初始化、条件、更新集中
未知次数,可能一次都不做while先判断后执行
至少要做一次do-while先执行后判断
无限循环for(;;)while(1)个人喜好

次数已知用 for,可能不做用 while,至少一次 do-while,无限循环看心情。

三、跳转语句

1.break的应用

1.1 基本用法

break用于立即跳出当前所在的循环或 switch 语句,不再执行循环中剩余的代码,也不再进行下一次循环。

使用场景作用
循环中(for/while/do-while)立即跳出整个循环
switch 中跳出 switch,防止穿透
嵌套循环中只跳出当前层循环!!!

1.2 在选择语句的应用

有break版本(正确)

int week = 3; switch (week) { case 1: printf("星期一\n"); break; // 跳出 switch case 2: printf("星期二\n"); break; case 3: printf("星期三\n"); break; // 执行到这里,跳出 switch default: printf("输入错误\n"); } // 输出:星期三

无break版本(穿透)(在特定情况下可以利用穿透的性质)

int week = 3; switch (week) { case 1: printf("星期一\n"); case 2: printf("星期二\n"); case 3: printf("星期三\n"); default: printf("输入错误\n"); } // 输出: 星期三(换行) 错误输入

1.3在循环语句的应用

for (int i = 1; i <= 10; i++) { if (i == 5) break; // i=5 时跳出循环 printf("%d ", i); } // 输出:1 2 3 4

2.continue的应用

2.1基本语法

continue用于跳过本次循环中剩余的代码,直接进入下一次循环。

使用场景作用
循环中结束本次循环,进入下一次
while/do-while 中注意循环变量更新位置

2.2 在 for 循环中的应用

for (int i = 1; i <= 5; i++) { if (i == 3) continue; // 跳过 i=3 printf("%d ", i); } // 输出:1 2 4 5

2.3在 while 循环中的应用

留意更新位置,避免使用continue语句跳过。

//错误:continue 跳过更新 int i = 1; while (i <= 5) { if (i == 3) continue; // 跳到下次循环,i++ 被跳过 printf("%d ", i); i++; // i=3 时这行不执行 → 无限循环 }

3.goto的应用

3.1 基本作用

goto用于无条件跳转到程序中指定的标签位置。

场景说明
跳出多层循环比标志位更直接
统一错误处理多个错误跳转到同一位置
清理资源函数结束前统一释放
goto 标签名; // ... 标签名: // 要跳转到的代码

示例:

//跳出多层循环 for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (i == 1 && j == 1) { goto end; // 直接跳出所有循环 } printf("(%d,%d) ", i, j); } printf("\n"); } end: printf("循环结束\n");

3.2 使用建议

唯一推荐的两种使用场景

场景示例
统一错误处理if (失败) goto cleanup;
跳出多层循环if (找到) goto found;

了解语法即可,实际编程中严禁使用,直到你成为经验丰富的开发者并遇到非用不可的场景。

http://www.cnnetsun.cn/news/1386771.html

相关文章:

  • C++ 实战:STL List 容器自定义排序深度解析
  • 从ViLT看多模态大模型进化:为什么说Transformer正在吃掉视觉领域?
  • AS32-TTL-100 LoRa模块嵌入式透传集成指南
  • Quartus II 13.0 实战:3种方法实现D触发器仿真(原理图+Verilog+ModelSim对比)
  • 热式(不可充电)电池市场洞察:2026 - 2032年复合增长率(CAGR)为10.1%
  • SNP芯片分型实战解析:从信号强度到GenomeStudio可视化
  • 计算机毕业设计springboot营养搭配家庭烹饪网站 基于SpringBoot的家庭膳食营养管理平台 SpringBoot智能家常菜谱推荐与营养分析系统
  • MySQL触发器实战:从语法解析到学生选课系统应用
  • 深度解析:攻击者常用 8 种防火墙绕过手法,原理 + 实战全公开
  • 永磁同步模型电流预测控制及滑模控制器结合新趋近律算法文献解读与探究
  • 收藏!IT后端转型AI大模型:多少程序员正在抓住新赛道?
  • Hello-Agents阅读笔记--基础篇--智能体的构成和运行原理
  • Keil5调试实战:从原理到高效问题定位的工程化指南
  • 项目解决方案:AI智能分析在无人机方面的应用方案
  • 信捷XDH Ethercat A_WRITE指令全解析:从参数配置到状态监控(保姆级教程)
  • 跨版本数据库连接困境:用pyodbc统一访问PG、opengauss与gaussdb
  • 摒弃有害厨具,京尚黑科技陶瓷锅,开启高端健康烹饪时代
  • 笔记本电脑外接显示器偶尔不亮
  • 搞懂SMART 200与宇电温控器的Modbus实战
  • 3分钟掌握RePKG:Wallpaper Engine资源提取与转换的终极解决方案
  • Qwen3-32B-Chat开源模型对比评测:Llama3-70B/Qwen3-32B/DeepSeek-V3推理效率PK
  • AFSim 2.9中文参考手册隐藏技巧大揭秘:提升效率的5个冷门功能
  • Qt 线程
  • 探索 Awesome GPT Agents:解锁AI助手在网络安全领域的无限可能
  • 探索Pandas-TA:技术分析图表库,助力金融数据分析
  • PP-DocLayoutV3部署教程:paddlepaddle-gpu安装验证与CUDA版本匹配指南
  • Python报错dh key too small的解决办法
  • 如何快速突破微信网页版限制:wechat-need-web完整解决方案指南
  • Zemax实战:攻克宽光谱高NA显微物镜的三大核心挑战
  • vue2+OpenLayers 天地图上打点(1)