关于c语言循环结构的一些思考

最近,我在看正点原子的usmart源码程序,当看到usmart_get_fname()函数的时候,其中有一部分代码我死活看不懂了,后来还是我问了一下vscode中的AI工具才明白源码作者的意图,于是我就产生了这样一个疑问"我是在不了解usmart协议具体内容的情况下直接看代码,发现有些代码看不懂,会不会是自己的代码功力不足导致的呢?"。我已经通过看视频以及平时利用下班时间自学过完整的c语言基础、高级用法,学过51单片机、stm32单片机、基于s5pv210芯片的嵌入式开发;平时在工作中也经常不间断的看我同事以前写的以及现在的代码,按理说经过这么多年时间的记录,我早已经不是刚毕业的菜鸟,c语言编程能力应该足够了,但是还是看不懂。

于是我在"知乎"和"CSDN"上将自己心里的这些疑惑描述了一下,有部分同行对我的疑问进行了解答,并提供了一些比较有建设性的意见,总之这种情况大家在工作中也经常遇到,遇到这种情况,不是自己c语言功力不足导致的,一是源码作者在写代码时是否注重编程规范,例如函数或者变量命名能够"信达雅",二是如果不了解业务逻辑直接去看代码,相当于一个被动接收的过程而不是一个用代码去验证业务逻辑的过程(代码是业务逻辑的反馈),这些都会造成看代码是容易被某一小段代码给"难住了"。

"知乎"和"CSDN"论坛中同行给我的2点建议是"不要在一点都不了解业务逻辑基础上知己看代码"和"通过先让代码运行起来,通过调试或者验证的方式先对业务功能有所了解,然后再去看懂代码"。

我觉得同行给的这些建议都比较有建设性,不过我在阅读usmart_get_fname()函数源码的时候,我还注意到之所以我不能读懂"一些临时变量的功能"并卡在这一小段代码上,还与我对"循环结构"的代码流程理解不清晰有关。我的意思是"之所以我看不懂是因为在一个循环结构中,需要结合下一次循环或者后面的变量的变化一起理解",我之所以看不懂那部分代码,是因为我没有继续阅读"下一次循环或者后面代码"的变量变化导致的。

因此,有必要对c语言循环结构的while()、do-while()、for三种形式的循环流程控制进行一次详细说明,在后面阅读代码的时候,尤其是在某个循环中遇到看不懂代码,先捋清楚循环流程控制,可能就能理解"不懂代码"有所帮助。

(1)while(条件判断)循环

cpp 复制代码
// 进入循环
while (条件判断)
{

    代码段;
}
code2;

流程大致是这样的:

首先进行一次"条件判断",如果结果为true,则运行一次"代码段",运行完后有调回继续判断"循环条件",如果结果为true,则继续运行第二次"代码段",否则直接跳转到while循环结尾继续运行后面代码。如果第一次"条件判断"结果为false,则直接跳过循环体里面的代码段,直接运行code2;第一次代码段运行完后绝对会造成"循环条件的变化",可能造成"条件判断"结果为false,否则一直循环下去了。有些关键字"return、break、continue、goto"也会对代码流向造成影响,这里就不再详细论述了。

(2)do-while(条件判断)

cpp 复制代码
// 进入循环
do
{
    // 循环体;
}while(条件判断)
// 后续代码
code2;

do-while(条件判断)对应现实中的案例就是"有一些情况,需要先做一次尝试,先尝鲜看看,根据尝鲜结果再决定是否继续"的情况;运行到do-while()循环后,无条件进入循环体,循环体代码运行完后再进行第一次"条件判断",当然"循环体"中的代码对"条件判断"的结果有直接作用影响。第一次"条件判断"如果为true则继续运行"循环体",如果为"false"则直接运行code2代码。后面的流程过程类似。do-while()循环和while()循环的关系是do-while()循环先进行一次无条件"循环体"运行,后面的流程就和while()循环一致了。

(3)for(初始化;条件;更新)循环

cpp 复制代码
// 进入驯化
for(变量初始化; 条件判断; 变量更新)
{
    // 循环体
}

// 后续代码
code2;

不知道大家有没有这样的一个疑问,for循环的条件判断为什么在for循环括号的中心位置呢,循环体运行完后,要运行"更新"再运行"条件判断"按照先后顺序是否更新在"中心位置"更合适呢?

我当时也有这样的疑惑,后来我为了一个AI,C语言设计的时候为什么要这样设计,后来才明白"条件判断"放在中心不是按照代码运行先后顺序,而是以人的理解习惯决定的。

进入for循环后,首先运行的是"变量初始化",初始化之后再运行第一次"条件判断",结果为true则运行循环体,否认直接跨过去运行"code2","循环体"运行完后跳回运行"变量更新",变量更新后再进行第二次"条件判断",如果结果为true怎继续运行"循环体",否则跳过"循环体"运行"code2"。我们发现"条件判断"在for循环的中心位置既照顾了"条件初始化"也照顾了"变量更新",而且有一个"内敛"的局势。

因此"条件判断"才是for循环的中心,"变量初始化"可以放在进入for循环之前和"变量更新"可以放在"循环体"中,因此for循环有很多变种,但是无论哪种"变种"处于中心位置的都是"条件判断"。

总之:

循环结构要想完全看懂循环体里面的内容,除了结合"循环体"的"上文"之外,还要节后循环体的"下文"以及循环的集体流程。如果不结合"下文"或者跳出循环后的(变量更新或者条件判断),不是完整的"循环流程",不能完全理解整个"循环流程"。

Tip:

循环体中如果有if-else条件判断遇到看不懂的情况,也需要结果循环体的"后文"以及跳出循环后的"条件判断",这样结合看就能大大提高if-else条件判断的概率。我以前也遇到过卡在了if条件判断的"代码段",怎么都看不懂为什么要这样操作了,这个时候我习惯去看else里面的代码发现也不能对理解if中的"代码段"有所帮助,于是就卡住了。我现在的逻辑就是先不管else里面的代码我直接看后面的"下文"以及上述三种循环结构跳出循环后的"条件判断"和"变量更新",这样结合看,看懂之后再去看else条件判断里面的内容,也是同样的操作。

因此循环结构中遇到代码看不懂的情况,需要结合后面的"后文"代码以及跳出循环后的"条件判断或者变量更新"结合一起看,也就是完成循环后面的工作,完成一次完整的循环工作,进入下一次循环,而不能在一次循环工作不完整的情况下里面循环体里面的"卡顿代码"。

相关推荐
Navigator_Z1 小时前
LeetCode //C - 1304. Find N Unique Integers Sum up to Zero
c语言·算法·leetcode
晓蛋1 小时前
C语言第1章概述.ppt
c语言·程序设计·概述·关键字·编译环境
学逆向的10 小时前
C 枚举变量
c语言·开发语言·网络安全
冷凝雨11 小时前
前导零、后导零、最高有效位、最低有效位计算(C)
c语言
鸥梨菌Honevid11 小时前
C 语言 restrict 关键字深度解析:从“独占访问”承诺到编译器激进优化
c语言
水饺编程16 小时前
第2章:Linux 基础,切换用户
linux·c语言·汇编
知识分享小能手17 小时前
C学习教程,从入门到精通,C语言学生信息管理系统 — 知识点详解(18)
c语言·学习·1024程序员节
爱读书的小胖17 小时前
LeetCode 55 跳跃游戏 C 语言解题分析
c语言·数据结构·算法·leetcode·1024程序员节
pipixia2003317 小时前
C++ 面试高频:namespace 的 6 个知识点,从 using 到匿名命名空间
c语言·学习·算法·嵌入式·命名空间·c++面试·匿名命名空间