欢迎来到进阶编程的世界!

你好!现在你已经掌握了编写程序的基础,是时候看看“大局”了。在本章中,我们将探讨进阶编程 (Further Programming)。我们会学习如何有效地组织数据,以及如何编写专业、易于修复且可重复使用的代码。这就像是从单纯拼砌乐高积木,转变为使用蓝图和专业工具组的建筑大师!

如果有些术语起初听起来有点吓人,不用担心。我们会用简单的类比和分步指南来为大家拆解。让我们开始吧!


1. 抽象数据类型 (Abstract Data Types, ADTs)

抽象数据类型 (ADT) 是一种组织数据及定义我们可以对其执行哪些操作的方法。想象一个“黑盒”:你知道什么数据放进去、什么数据出来,但为了使用它,你不一定需要看到里面复杂的线路。

A. 堆栈 (Stack)

堆栈 (Stack) 是一种遵循 LIFO (后进先出) 原则的数据集合:Last-In, First-Out

现实生活类比: 想象自助餐厅里的一叠托盘。最后放上去的那一个托盘,一定是别人第一个拿走的。你不可能在不把整叠弄倒的情况下,直接抽出最底下的那个!

关键操作:

  • Push (推入): 在顶部添加一个项目。
  • Pop (弹出): 从顶部移除一个项目。
  • Peek (查看): 查看顶部的项目而不将其移除。

B. 队列 (Queue)

队列 (Queue) 遵循 FIFO (先进先出) 原则:First-In, First-Out

现实生活类比: 一队等巴士的人。第一个到达的人第一个上车,这样才公平嘛!

关键操作:

  • Enqueue (加入): 在队伍的末端添加一个项目。
  • Dequeue (移出): 从队伍的前端移除一个项目。

C. 链表 (Linked List)

链表 (Linked List) 是一种数据集合,其中每个项目(称为节点 Node)都指向下一个项目。

现实生活类比: 寻宝游戏。你找到一个线索,而该线索会确切告诉你下一个线索在哪里。这些项目在内存中不一定需要紧挨着放置,它们只需要“知道”邻居在哪里即可。

快速复习: 堆栈使用 LIFO(像盘子),队列使用 FIFO(像排队),而链表使用指针 (Pointers) 来连接数据。


2. 结构化编程:过程与函数

随着程序变得越来越大,编写一长串代码会变成一场噩梦。结构化编程 (Structured Programming) 是一门将代码拆分为更小、可重复使用的区块(称为子程序 Sub-routines)的艺术。

过程 (Procedures) 与 函数 (Functions)

两者都是执行任务的代码区块,但有一个主要区别:

  • 过程 (Procedures): 执行任务但不会向主程序回传值例子:一个显示“欢迎”信息的过程。
  • 函数 (Functions): 执行计算并必须回传一个值例子:一个输入两个数字并回传其总和的函数。

参数传递:传值与传址

当你将数据传入子程序时,你会使用参数 (Parameters)。有两种方式可以做到:

1. 传值 (Passing by Value, ByVal): 程序会制作一份数据的副本。子程序外部的原始变量保持安全且不被改变。

2. 传址 (Passing by Reference, ByRef): 程序会将原始变量的地址传给子程序。如果子程序改变了该数值,原始变量也会随之改变!

记忆小撇步: ByVal 就像给朋友一张你功课的影印本。他们可以在上面随便涂写,但你的原稿是安全的。ByRef 就像把你的笔记本正本给他们。他们做的任何更改都是永久性的!

关键要点: 当你需要获取结果时,请使用函数。如果你想保护原始数据免受意外更改,请使用 ByVal


3. 程序设计与结构图

在开始输入代码之前,你需要一个计划。逐步求精 (Stepwise Refinement) 是一个将复杂问题拆解成越来越小的子问题,直到它们易于编码的过程。

结构图 (Structure Charts)

结构图 (Structure Chart) 是一种显示这些子问题(模块)如何相互连接的图表。它使用特定符号来显示数据如何流动:

  • 矩形: 代表一个模块(过程或函数)。
  • 带有空心圆的箭头: 显示数据偶对 (Data Couples)(在模块之间传递的数据)。
  • 带有实心圆的箭头: 显示控制标志 (Control Flags)(简单的真/假信号,例如“已完成”)。

你知道吗? 将问题分解使得团队合作更容易。一个人可以编写“登录”模块,而另一个人编写“付款”模块!


4. 测试与维护

即使是最优秀的程序员也会犯错!我们称这些为错误 (Bugs)。为了找到它们,我们使用不同的测试方法。

错误类型

  • 语法错误 (Syntax Error): 你违反了编程语言的规则(例如拼写错误或漏掉括号)。代码无法执行。
  • 逻辑错误 (Logic Error): 代码可以执行,但给出了错误的答案。(例如,你使用了 \( + \) 而不是 \( * \))。
  • 运行阶段错误 (Run-time Error): 在程序运行期间发生了无法处理的情况,例如尝试除以零。

选择测试数据

测试程序时,你应该使用三类数据:

  1. 正常数据 (Normal Data): 程序预期会收到的数据(例如,输入“15”作为年龄)。
  2. 异常数据 (Abnormal Data): 错误类型的数据(例如,输入“你好”作为年龄)。
  3. 极端/边界数据 (Extreme/Boundary Data): 处于允许范围边缘的值(例如,如果年龄限制为 18-65,则测试“18”和“65”)。

维护:让程序保持活跃

一旦程序发布,它仍然需要维护。这称为维护 (Maintenance)

  • 更正性维护 (Corrective): 修复软件发布后发现的错误。
  • 适应性维护 (Adaptive): 修改程序以使其能在新的操作系统或新的硬件上运作。
  • 完善性维护 (Perfective): 添加新功能或优化代码执行速度,使其变得“完美”。

常见错误: 许多学生会混淆适应性完善性。请记住:适应性是关于必要性(否则无法运作),而完善性是关于改进(虽然能运作,但你希望它更好)。


最终快速复习框

- ADTs: 堆栈 (LIFO)、队列 (FIFO)、链表 (指针)。
- 结构: 函数回传值;过程不回传值。ByVal = 安全副本;ByRef = 存取原始数据。
- 设计: 使用结构图来规划模块间如何共享数据。
- 测试: 使用正常、异常和边界数据来找出语法、逻辑和运行阶段错误。
- 维护: 更正性(修复)、适应性(变更环境)、完善性(改进)。

你一定做得到的!编程是一项通过练习而不断进步的技能。继续编码,继续探索吧!