你好,未来的计算机科学家!这一章非常重要。我们即将超越单纯的代码编写,开始学习如何像专业的软件工程师一样去“设计”程序。“结构化方法”是构建大型、可靠且易于理解的软件的基础技术。把它想象成是在整理你的编程工具箱——有了它,你不仅能搭建简陋的小棚屋,还能建造出摩天大楼!

别担心这些术语听起来过于正式;我们将通过简单的例子为你拆解它们。

3.3.1 结构化编程方法

结构化方法是一种程序设计理念。这意味着我们使用一套有限的逻辑控制结构(如选择和迭代)来构建程序,而最重要的一点是,将程序分解为更小的、自包含的逻辑块。

结构化设计背后的核心概念

程序设计部分中的两个基本概念可以帮助我们有效地使用结构化方法:

1. 分解 (Decomposition) (教学大纲 3.3.2)
类比:准备一顿大餐。

分解是将复杂问题拆解为若干个更小、更易于管理的问题(或任务)的过程。每个子问题都应执行一项可识别的特定任务。在编程中,这些任务通常通过子程序 (subroutines) 来实现。

2. 抽象 (Abstraction) (教学大纲 3.3.2)
类比:使用遥控器。

抽象是指移除问题中不必要的细节,以便简化解决方案。在编写子程序时,你只需要知道它做什么,而不必关心它内部如何执行每一个计算。这简化了大型程序的结构。

快速回顾:目标

结构化方法的主要目标是确保代码清晰、合乎逻辑且易于测试,这通常通过受控的模块来实现。

3.3.1.1 模块化编程

模块化编程是分解的具体应用。我们不再编写一个巨大的代码块,而是创建单独的、可重用的块,称为模块 (modules)子程序 (subroutines)(过程或函数)。

子程序是一段有名字的“独立”代码块,只需在程序语句中写下其名称即可执行(调用)(教学大纲 3.1.2.7)。

模块化的优势
  • 易于调试:如果程序运行失败,你知道错误被限制在某个特定的模块内,这使得定位和修复变得更容易。
  • 可重用性:一旦编写好一个模块(例如计算税额的函数),它就可以在同一个程序中多次使用,甚至可以在完全不同的程序中使用。
  • 可维护性:如果需求发生变化,你只需要更新特定的模块,而无需改动系统的其余部分。
  • 团队协作:多名程序员可以同时处理不同的模块,从而加快开发速度。

3.3.1.2 控制流与数据:参数和作用域

为了让模块以结构化的方式有效协同工作,我们需要制定关于它们如何交换数据以及如何管理变量的严格规则。

A. 参数与返回值

模块使用参数 (parameters) 来接收来自调用程序的输入数据,并使用返回值 (return values) 将计算结果回传。

  • 参数:子程序被调用时传入的数据。
  • 返回值:由子程序计算得出并返回给调用程序的数据。

示例:如果你有一个名为 CalculateArea(计算面积)的模块,其参数可能是 (Length, Width)(长度、宽度),而返回值将是 Area(面积)。

B. 局部变量与全局变量的使用

作用域 (scope) 的概念定义了变量在程序中何处可以被访问或修改。控制作用域对于结构化至关重要,因为它能防止模块之间意外干扰彼此的数据。

1. 全局变量 (Global Variables) (教学大纲 3.1.2.7)

  • 定义:在任何子程序之外声明的变量,在整个程序中都可以访问和修改。
  • 风险:如果多个模块都可以更改同一个全局变量,那么追踪“为什么”以及“何时”会出现意料之外的值将变得极其困难。这是糟糕的结构!

2. 局部变量 (Local Variables) (教学大纲 3.1.2.7)

  • 定义:在特定的子程序(或代码块)内声明的变量。
  • 可访问性:它们仅在子程序执行期间可被访问,且仅在该子程序内可见。
  • 优势(良好习惯):将变量作用域限制在局部是良好的编程习惯。它确保了一个模块内的操作不会对程序的其他部分产生意外的副作用。

你知道吗?
局部变量在子程序运行结束后就会“销毁”,从而释放内存。而全局变量则会一直存在,直到整个程序终止。

避免常见的错误!

过度依赖全局变量违背了模块化的初衷。如果你的模块频繁地读取/写入全局数据,它们就不再是真正独立的了。请尽量使用参数和返回值来代替!

3.3.1.3 设计结构:层次图与结构图

使用结构化方法时,我们需要在写代码之前,利用工具来可视化分解情况及模块间的关系。这就是图表发挥作用的地方。

A. 层次图 (Hierarchy Charts)

层次图(也称 H-Chart)以自顶向下的方式展示程序中模块之间的关系。它显示了谁调用了谁

  • 最顶层的框代表主程序。
  • 下方每一层显示了由上层模块调用的子模块。
  • 它们仅关注控制流(执行顺序)。

类比:公司的组织架构图。CEO(主程序)将任务委派给经理(模块 A、模块 B),经理再委派给员工(子模块)。

B. 结构图 (Structure Charts)

结构图比层次图更详细。它们不仅展示控制流(谁调用谁),还展示了模块之间的数据流

  • 它们使用带标签的箭头来指示模块之间传递了哪些数据(参数和返回值)。
  • 这些图表帮助设计者确保模块真正相互独立,并且仅通过定义的接口(参数)进行通信。

设计图表的核心要点:
层次图展示模块的拆解和控制逻辑;结构图则增加了关于模块间交换具体数据的细节。

总结:为什么结构很重要

结构化编程方法依赖于三大支柱:

  1. 模块化:将程序拆解为独立的子程序。
  2. 受控的数据交换:使用参数和返回值,而不是依赖全局变量。
  3. 受控的作用域:在模块内部使用局部变量,以防止对程序的其余部分产生意想不到的副作用。

通过遵循这种方法,你将确保你的程序稳健、易于维护且逻辑严密——这对任何严谨的程序员来说都是必备技能!