程序像河水一样流动着

摘要

  • “程序像河水一样流动着” 主要探讨了程序执行的流程及相关概念。
  • 首先介绍了程序计数器(PC)在确定程序执行顺序中的关键作用,它如同指挥棒决定着下一条指令的地址。

  • 接着阐述了条件分支和循环机制,条件分支根据特定条件改变程序的执行路径,而循环则通过重复执行一段代码实现特定功能。

  • 同时,详细说明了标志寄存器在条件判断中的重要性,其存储的标志位可反映运算结果的状态,为条件分支提供依据。

  • 此外,还通过具体的示例和代码片段,直观地展示了程序的流动过程,为理解计算机程序的执行方式提供了深入的视角。

程序的流程分为3种

从硬件上想计算机的运作方式:硬件系统由 CPU、I/O 和内存三部分构成。

内存中存储着程序。(程序:指令+数据);CPU 配合着时钟信号,从内存中读出指令,再依次对其进行解释和执行。

为了解释程序的流程/流向,先介绍一下CPU怎么读取指令的:

PC寄存器

PC寄存器(Program Counter,程序计数器),负责存储内存地址,该地址指向下一条即将执行的指令。每解释执行完一条指令,PC 寄存器的值就会自动被更新为下一条指令的地址。

顺序执行

假设 PC 寄存器正指向内存中一个从 10 号地址开始的 3 字节指令。CPU 解释执行完这条指令后,PC 寄存器中的值就变成 10+3 = 13 了。也就是说,程序基本上是从内存中的低地址(编号较小的地址)开始,向着高地址(编号较大的地址)流下去的 。我们把程序的这种流动称为“顺序执行”。

“条件分支”和“循环”

顺序执行是按照指令记录在内存中的先后顺序依次执行的一种流程。而循环则是在程序的特定范围内反复执行若干次的一种流程。条件分支是根据若干个条件的成立与否,在程序的流程中产生若干个分支的一种流程。无论规模多么大多么复杂的程序,都是通过把以上三种流程组合起来实现的。

像河流

从高山的泉眼中涌出的清泉形成了河流的源头(程序执行的起点)。水流从山中缓缓流下,有时向着一个方向流淌(顺序执行),有时中途分出了支流(条件分支),还有时由于地势卷起了漩涡(循环)。难道诸位不认为程序的流程也很美吗?完全就像是裱在画轴上的山水画一样。

用 VBScript编写游戏代码

' 初始化表示手势的变量
Dim gesture(2)
gesture(0) = " 石头 "
gesture(1) = " 剪刀 "
gesture(2) = " 布 "
' 初始化对玩家获胜次数计数的变量
wins = 0
' 初始化随机数种子
Randomize
' 显示程序启动信息
MsgBox " 石头剪刀布游戏 Ver.1.00 by H.Yazawa "
' 进行五轮比试
For i = 1 To 5
' 输入玩家的手势
user = CInt(InputBox("0: 石头、1: 剪刀、2: 布 "))
' 用随机数决定计算机的手势
computer = CInt(Rnd * 2)
' 生成提示双方出的手势的字符串
s = " 玩家:" & gesture(user) & "、计算机:" & gesture(computer)
' 判定胜负,显示结果
If user = computer Then
MsgBox s & "... 平局! "
ElseIf computer = (user + 1) Mod 3 Then
MsgBox s & "... 玩家获胜! "
wins = wins + 1
Else
MsgBox s & "... 计算机获胜! "
End If
Next
' 显示玩家的获胜次数
MsgBox " 玩家获胜次数: " & wins

用流程图表示程序的流程

上述代码转化为流程图如下(流程图画法省略)

如需详细学习,参考:https://www.cnblogs.com/WiseAdministrator/articles/11084202.html

流程图如何处理循环(略读)

  • “帽子” 和 “短裤” 符号在高级语言中的应用:在使用程序块的高级语言中,用 “帽子”(如 for 语句的起始部分)和 “短裤”(如对应的大括号结束部分)符号表示循环结构。“帽子” 中设定循环条件,控制循环的开始和结束条件。
  • 与机器语言和汇编语言实现循环的区别:机器语言和汇编语言通过跳转指令实现循环,根据比较操作的结果跳转到之前的地址形成循环,或跳转到后续地址进行条件分支;而高级语言通过程序块使循环结构更清晰,易于理解和编写。

  • 例子一:数组元素查找:例如,在从数组 x 中查找特定数字(如 777)的程序中,高级语言使用类似for (i = 0; i < 1000; i++)的语句作为 “帽子”,设定循环范围,在循环体中通过if语句判断是否找到目标数字,整个循环结构清晰易懂。
  • 例子二:学生成绩筛选:假设要从存储学生成绩的数组中找出成绩高于 90 分的学生,高级语言可这样实现:for (int i = 0; i < 数组长度; i++) { if (学生成绩[i] > 90) { 执行相关操作(如记录学生信息等)} },这里的for语句是 “帽子”,大括号内的内容为循环体,执行具体的查找操作,循环结束时相当于 “短裤” 的作用。

针对这块的严谨表述(略读)

循环界限:循环界限为去上角矩形或去下角矩形,分别表示循环的开始和循环的结束。一对符号内应注明同一循环标识符。可根据检验终止循环条件在循环的开始还是在循环的末尾,将其条件分别在上界限符内注明(如:当A>B)或在下界限符内注明(如:直到C<D)。
图例:给出了当终止条件成立时进入循环和直到终止条件成立退出循环的两种不同的表示。

结构化程序设计

  • 结构化程序设计的定义:结构化程序设计主张仅用顺序执行、条件分支和循环表示程序流程,不使用跳转指令,以提升程序的结构性和可读性。
  • 其目的和意义:旨在提高开发大型程序的效率,使程序更易于维护。避免程序陷入 “意大利面条” 般的混乱状态,使代码更易于理解和调试。

结合例子来总结:

  • 例子一:工资计算程序:假设我们有一个用于员工薪资管理的程序,按照结构化程序设计的原则,会将程序的功能分解为清晰的模块。比如,计算工资的规则会明确地表示为一系列的步骤,而不是使用复杂的跳转指令。这样,当薪资计算规则变更时,只需修改相关的模块,比如调整计算工资的函数,而不会影响整个程序的结构,使得维护更加轻松。
  • 例子二:文件共享系统:在一个文件共享型系统中,结构化程序设计可以确保不同部分的代码相互独立且易于管理。例如,负责文件存储和读取的部分、用户权限管理的部分以及文件共享逻辑的部分,都可以按照结构化的方式进行设计,使得各个部分的功能明确,相互之间的交互清晰,便于系统的维护和扩展。

⭐重点⭐

以上对结构化程序设计的讲解,严格按照WWH的方式进行,是什么,为什么,怎么做。

理解——记忆——运用。

⭐重点⭐

其实这样理解知识是很抽象的,我们必须结合实际的例子来说明,因为每个知识的产出,他都是为了解决或者优化之前的某一部分内容。现在我们光看这样的知识罗列,我们并不知道,它是怎么产出的,它产出是为了什么,之前的困难是什么导致它的产出。

就拿这个结构化程序设计举例:

其目的和意义:旨在提高开发大型程序的效率,使程序更易于维护。避免程序陷入 “意大利面条” 般的混乱状态,使代码更易于理解和调试。

我们不知道:

  • 它怎么提高了效率
  • 怎么使得更易维护
  • 意大利面条混乱状态是什么
  • 为什么更容易理解和调试

毫不夸张的说,这段解释,如果没有一定的知识储备,可以说读了一段天书一样。

综上所述,我们学习知识,都需要一些东西去做铺垫,有一定的储备,才能一步步的往上爬。有个东西叫知识茧房,就是作者他在介绍这个东西的时候,默认你这些基础的都知道,但是有时候我们并不知道,办法只有一点点学了。直接理解抽象的概念是行不通的。

画流程图来思考算法

  • 思考算法的要点:先从整体上考虑程序的粗略流程,再细化各个部分的流程。
  • 通过验算确保算法正确性:在纸上画完或写完流程以后,再把具体的数据代入以跟踪流程的处理,确认是否能得到预期的结果。在验算的时候,建议使用简单的数据,这样即使是用心算也能得出正确的结果。

结合例子来总结:

  • 例子一:石头剪刀布游戏判定输赢:假设要设计一个石头剪刀布游戏的算法,首先在纸上画出流程图,大致确定游戏的流程,包括玩家出拳、判断输赢、显示结果等步骤。然后,具体细化每个步骤,比如如何确定玩家的出拳、如何根据规则判断输赢等。在验算时,可以用简单的数据,如假设玩家 A 出石头,玩家 B 出剪刀,按照算法流程判断输赢,确保结果符合预期。
  • 例子二:简单计算问题:例如计算两个数的和的算法,先在纸上画出流程,包括输入两个数、进行加法运算、输出结果等步骤。然后用具体的数,如 2 和 3 进行验算,看是否能得到正确的和 5,以验证算法的正确性。

特殊的程序流程 —— 中断处理

  • 中断处理的定义:计算机使程序的流程突然跳转到程序中的特定地方,这个地方被称为中断处理例程或中断处理程序,而这种跳转是通过 CPU 所具备的硬件功能实现的。
  • 中断处理的过程:以硬件形式连接到 CPU 上的 I/O 模块会发出中断请求信号,当 CPU 接收到这个信号时,会执行相应的中断处理程序。例如,用户按下键盘上的按键,键盘上的 I/O 模块就会把中断请求信号发送给 CPU,CPU 通过这种方式知道有按键被按下,于是从 I/O 设备读入数据。
  • 中断处理的特点:中断处理以从硬件发出的请求为条件,使程序的流程产生分支,因此可以说它是一种特殊的条件分支。处理中断请求的程序内置于被烧录在计算机 ROM 中的 BIOS 系统中,或内置于 Windows 等操作系统中。

结合例子来总结:

  • 例子一:键盘输入:当用户在编辑文档时,按下键盘上的按键,键盘会向 CPU 发送中断请求信号。CPU 响应中断后,暂停当前的程序流程,转而执行与键盘输入相关的中断处理程序,将用户输入的字符读入并显示在文档中,然后再回到原来的程序流程继续执行。
  • 例子二:鼠标操作:在使用图形界面的操作系统时,移动鼠标或点击鼠标按键会产生中断请求。CPU 接收到这些请求后,执行相应的中断处理程序,实现鼠标指针的移动、点击操作的响应等功能,从而实现用户与计算机的交互。

特殊的程序流程 —— 事件驱动

  • 事件驱动的概念:程序员用事件驱动的方式编写在 Windows 操作系统中的应用程序。在这种方式中,程序的运行由事件来驱动,当某个事件发生时,程序会相应地执行特定的处理。
  • 事件驱动的实现:例如,在一个简单的文本编辑软件中,当用户点击 “打开文件” 菜单项时,就会触发一个事件。操作系统会检测到这个事件,并通知应用程序。应用程序接收到这个通知后,就会执行打开文件的相关操作,如显示文件选择对话框、读取文件内容等。
  • 与其他编程方式的区别:使用事件驱动编程与传统的过程型语言不同,传统过程型语言通常使用流程图来表示程序的运行过程,而事件驱动编程使用 UML 中的时序图和协作图来表示程序的运行过程。在时序图中,把用矩形表示的对象横向排列,从上往下表示时间的流逝,用箭头表示对象间的消息传递(即程序上的函数调用)。

结合例子来总结:

  • 例子一:计算器应用程序:在一个计算器应用程序中,当用户点击数字按钮时,会触发相应的事件,程序会根据这个事件将数字显示在屏幕上。当用户点击运算符按钮时,也会触发事件,程序会根据当前的输入和操作数进行相应的计算。例如,用户依次输入 “2” “+” “3” “=”,每次输入都会触发事件,程序会根据事件执行相应的操作,最终显示出结果 “5”。
  • 例子二:网页浏览器:当用户在网页浏览器中点击链接时,会触发一个事件。浏览器接收到这个事件后,会向服务器发送请求,获取链接对应的网页内容,并在浏览器中显示出来。同时,浏览器还会处理其他事件,如滚动页面、调整窗口大小等,根据不同的事件执行相应的操作,以提供良好的用户体验。

posted on   亮星晨  阅读(15)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示