简介:结构化与逻辑编程

欢迎来到结构化编程 (Structured Programming) 的章节!别担心这个名字听起来很复杂,它其实只是一套规则与最佳实践,能帮助我们写出清晰、易读且容易修正(调试/debug)的代码。

你可以把结构化编程想象成拼乐高积木。与其随意乱堆,你通过说明书(结构)来确保你的成品既稳固又合理。

掌握了这些概念后,你将学会如何将代码组织成强大且合乎逻辑的步骤。这对每一位计算机科学家来说都至关重要!


1. 结构化编程的基石

结构化编程完全依赖三个基础控制结构。无论你编写的程序有多复杂,终究都只会运用这三种技术。

1.1 顺序结构 (Sequence / 按步执行)

顺序结构是最基本的控制结构。这意味着程序中的指令会按照它们编写的确切顺序,一条接一条地执行。

类比: 参考食谱或系鞋带。你必须先完成第 1 步,才能继续进行第 2 步,以此类推。

• 执行指令 A。
• 接着执行指令 B。
• 最后执行指令 C。

重点笔记: 顺序结构决定了程序执行时由上而下的线性流向。

1.2 选择结构 (Selection / 做出决策)

选择结构(或称条件分支/Conditionals)允许程序根据特定条件为真(TRUE)或为假(FALSE)来做出决策,进而决定程序将执行哪一条指令路径。

我们常用到的架构包括 IFELSE IF(有时写作 ELIF)以及 ELSE

选择结构如何运作:

1. 程序检查一个条件(例如:气温是否高于 20 度?)。
2. 如果条件为 TRUE,则执行一段代码。
3. 如果条件为 FALSE,则可能执行另一段不同的代码(即 ELSE 的部分)。

示例:

IF (User_is_18_or_older) THEN
    DISPLAY "欢迎,请进。"
ELSE
    DISPLAY "拒绝访问。"
END IF

重要提示: 当你需要检查多个条件时,请使用 ELSE IF (ELIF),而 ELSE 则会捕获所有未符合上述条件的情况。

快速回顾: 选择结构让你的程序能从两个或多个可能性中选择一条路径。

1.3 循环结构 (Iteration / 重复与循环)

循环结构是指将一段代码重复执行多次。这对于节省时间并提升程序效率极为有用(试想如果必须手写 100 次 "print 'Hello'" 会有多累!)。

你需要知道两种主要的循环结构类型:

1.3.1 固定次数循环 (Definite Iteration):FOR 循环

当你预先精确知道代码需要重复多少次时使用。这是一种计数控制循环 (count-controlled loop)

类比: 在健身房计算次数。你预先决定要做 10 个俯卧撑(循环精确重复 10 次)。

FOR Count FROM 1 TO 10 DO
    // 代码块将执行 10 次
END FOR

1.3.2 条件控制循环 (Indefinite Iteration):WHILE 与 REPEAT 循环

当你预先不知道代码需要重复的确切次数时使用。循环取决于条件:

1. 前测条件循环 (WHILE...DO...END WHILE): 在执行代码块之前检查条件。如果一开始条件为假,循环体可能根本不会执行。

WHILE (Score_is_less_than_100) DO
    Add_Points()
END WHILE

2. 后测条件循环 (REPEAT...UNTIL): 先执行代码块,然后在结尾测试条件。因为检查是在底部进行,所以里面的代码至少会执行一次

REPEAT
    Enter_Password()
UNTIL (Password_is_valid)

避免常见错误:死循环 (The Infinite Loop)!
如果循环中的条件永远无法被满足或改变(例如 WHILE 5 > 2 DO...),循环将会永远执行下去,导致程序卡住或崩溃。请务必确保循环体会更新条件中测试的变量!


2. 模块化编程:过程、函数与变量作用域

随着程序规模扩大,管理起来会变得更加困难。模块化编程 (Modular Programming)(或称自顶向下设计/top-down design)通过将庞大的程序分解成较小、独立的迷你程序(称为模块 (modules)子程序 (sub-programs))来解决此问题。

2.1 为什么要使用模块(子程序)?

使用过程与函数非常重要,因为它可以促进:

可读性 (Readability): 主程序看起来更简洁,更容易理解。
可维护性 (Maintainability): 如果发生错误(bug),你只需要查看该小型模块,而不需要翻遍整个庞大的程序。
可重用性 (Reusability): 你可以在程序的不同部分重复使用同一个模块(例如:计算税额),甚至在不同程序中重复使用,而无需重新编写。

2.2 过程 (Procedures)

过程是一组已命名的指令序列,旨在执行特定的任务。

• 它们用于执行某个动作(例如:显示消息、保存文件)。
• 过程执行完其指令后,会将控制权交回给主程序。
• 关键点在于,它们不一定会返回值

示例: 一个过程可能名为 DisplayWelcomeMessage()。它执行其动作(显示消息)然后结束。它不会进行计算或返回任何结果。

2.3 函数 (Functions)

函数与过程相似,但有一个关键差异:

• 函数旨在计算出一个数值
• 函数必须返回一个值给主程序(或调用它的代码段)。
• 它们就像迷你计算器。

示例: 一个函数可能名为 CalculateArea()。你给它宽与高,它执行计算,并返回计算后的面积值。

记忆小技巧: Function (函数) 总是会返回一个 Final (最终) 答案(数值)。而过程只是单纯遵循指令。

2.4 参数 (Parameters / 传递数据)

我们如何将数据传入过程与函数,让它们完成工作?我们使用参数 (Parameters)(有时称为实参 / Arguments)。

参数是一种用来在调用子程序时,将数据或信息传入其中的变量。

类比: 如果你的函数是果汁机,参数就是你放入果汁机的配料(水果、牛奶),这样它才能制作果昔。

当你定义一个函数或过程时,你需要指定它所预期的参数:

FUNCTION CalculateArea (Width, Height)
    Area = Width * Height
    RETURN Area
END FUNCTION

当主程序调用 (calls) 此函数时,它会提供实际的数据:

My_Space = CalculateArea(10, 5) // 10 和 5 是被传入的值

在此示例中:WidthHeight 是函数中定义的参数,而 105 则是使用函数时传递给这些参数的数值。

2.5 变量作用域:局部变量与全局变量

作用域 (Scope) 是指变量在程序不同部分中的可见性与可访问性:

局部变量 (Local Variables): 在特定子程序(函数或过程)内部声明。它们在子程序执行时被创建,并在子程序结束时被销毁。无法从该子程序外部访问或修改它们。
全局变量 (Global Variables): 在主程序中声明,可在整个程序中的任何地方访问。

为什么优先使用局部变量:
局部变量可以防止意外的副作用(对程序其他部分数据造成的非预期变更)、使子程序自成一体且更易于重用,并在子程序执行完毕后释放内存。

你知道吗? 模块化编程在 1960 年代是一个革命性的概念!在那之前,代码通常被写成一长串令人困惑的块,让调试成为一场彻底的噩梦。结构化编程让复杂软件的诞生变得可能!


快速回顾盒:结构化编程精华

三大控制结构:

1. 顺序结构 (Sequence): 按照先后次序做 A,接着做 B,最后做 C。
2. 选择结构 (Selection): 使用 IF、ELSE IF (ELIF) 和 ELSE 检查条件。
3. 循环结构 (Iteration): 使用固定次数循环 (FOR) 或条件控制循环 (WHILE、REPEAT...UNTIL) 重复代码。

模块化编程与作用域:

过程 (Procedure): 执行任务;不需要返回值。
函数 (Function): 计算数值;必须返回值。
参数 (Parameter): 调用时传入子程序的数据。
局部作用域 (Local Scope): 变量仅限于子程序内部,避免非预期的全局副作用。