欢迎来到编程概念的世界!

你好,未来的程序员!这一章节是真正充满乐趣的开始。我们将从理解计算机如何工作(硬件和数据),转向为计算机提供具体的、分步骤的指令——这就是编程的全部意义所在!

掌握这些基础概念将使你能够设计、编写并理解任何算法,为你应对 Paper 2 中实际的问题解决题型打下坚实的基础。如果代码一开始看起来有些陌生,不必担心;我们会将一切拆解成易于理解的部分。让我们开始吧!

8.1 编程概念:构建基石

8.1.1 变量与常量

可以将变量和常量想象成计算机内存中带有标签的存储盒。

变量 (Variables)

变量是一个内存位置,用于存储在程序执行期间可以改变的值。
示例:玩家的得分(Score)会随着游戏进行而改变。

常量 (Constants)

常量是一个内存位置,用于存储在程序执行期间不能改变的值。
示例:圆周率 (\(\pi\)) 的值或固定的税率(TaxRate)。

在伪代码中,我们使用关键字来声明它们:

  • 变量声明:
    DECLARE TotalScore : INTEGER
  • 常量声明:
    CONSTANT MaxAttempts ← 3
  • 赋值: 我们使用赋值运算符 将值存入变量。
    TotalScore ← 100

8.1.2 基本数据类型

当你声明一个变量或常量时,必须告知计算机它将存储哪种数据类型。这有助于计算机分配正确的内存空间并防止错误。
类比:数据类型就像是容器上的标签——如果标签写着“水”,你就不会试图往里装电了!

你需要掌握的基本数据类型包括:

  • INTEGER(整数): 整数(正数、负数或零)。没有小数点。
    常量示例:5, -100, 0
  • REAL(实数): 可以包含小数部分的数字。
    常量示例:3.14, -0.5, 4.0
  • CHAR(字符): 单个字母、数字或符号。用单引号括起来。
    常量示例:'A', '7', '@'
  • STRING(字符串): 字符序列(文本)。用双引号括起来。
    常量示例:"Hello World", "CS0478"
  • BOOLEAN(布尔值): 逻辑值,只能为 TRUE(真)或 FALSE(假)。
    常量示例:TRUE, FALSE
快速回顾:

如果你要存储某人的年龄,使用 INTEGER。如果你要存储他们的名字,使用 STRING。如果你要检查灯是“开”还是“关”,使用 BOOLEAN

8.1.3 输入与输出 (I/O)

程序需要与用户交互。这通过 I/O 命令来处理。

  • INPUT(输入): 从用户(通常是键盘)读取数据并将其存储在变量中。
    语法:INPUT <变量>
    示例:INPUT UserName
  • OUTPUT(输出): 向用户显示数据或信息(通常是屏幕)。
    语法:OUTPUT <值>
    示例:OUTPUT "Hello, ", UserName

8.1.4 (f) 运算符

运算符是用于执行计算或比较的特殊符号。

算术运算符(计算)

用于执行数学运算:

  • + (加法)
  • - (减法)
  • * (乘法)
  • / (除法,结果为 REAL 实数)
  • ^ (乘方,例如 \(2^3\))
  • DIV: 整除(返回商,舍弃余数)。
    示例:DIV(10, 3) 返回 3
  • MOD: 取模(返回整除后的余数)。
    示例:MOD(10, 3) 返回 1

记忆窍门: MOD 是除法后的“剩菜”(余数)。DIV 是除法能完全进入多少次。

关系运算符(比较)

用于比较两个值,始终返回一个 BOOLEAN 结果(TRUE 或 FALSE)。

  • = (等于)
  • < (小于)
  • <= (小于等于)
  • > (大于)
  • >= (大于等于)
  • <> (不等于)
逻辑运算符(组合条件)

用于组合多个布尔条件。

  • AND(与): 仅当所有条件都为 TRUE 时,结果才为 TRUE。
  • OR(或): 只要至少有一个条件为 TRUE,结果即为 TRUE。
  • NOT(非): 反转条件(TRUE 变为 FALSE,FALSE 变为 TRUE)。

示例:IF (Age > 18) AND (IsCitizen = TRUE) THEN...

运算符关键要点: 算术运算符产生数字。关系和逻辑运算符产生 BOOLEAN 值(用于决策)。

8.1.4 控制结构:顺序、选择、迭代

(a) 顺序结构 (Sequence)

顺序结构是最简单的控制结构。指令按照它们出现的顺序一条接一条地执行。这是程序的默认执行流。

示例:
1. Total ← 0
2. Number1 ← 10
3. Total ← Total + Number1

(b) 选择结构 (Selection)

选择结构允许程序根据条件(布尔测试)来决定执行哪段代码。

IF 语句

用于一到两种可能的结果:

IF <条件> THEN
    <语句>
ELSE
    <语句>
ENDIF
CASE 语句

当基于单个变量的值有多种可能的结果时使用。

INPUT Grade
CASE OF Grade
    'A' : OUTPUT "Excellent"
    'B' : OUTPUT "Good"
    OTHERWISE OUTPUT "Needs Improvement"
ENDCASE
嵌套语句 (8.1.5)

嵌套语句是指一个选择或迭代结构完全包含在另一个结构内部。这对于处理复杂逻辑至关重要。
考试中你不需要编写超过三层嵌套的语句。

嵌套 IF 示例:

IF Score > 50 THEN
    IF Score > 90 THEN // 嵌套 IF
        OUTPUT "Top result!"
    ELSE
        OUTPUT "Pass"
    ENDIF
ELSE
    OUTPUT "Fail"
ENDIF

(c) 迭代结构 (Iteration/Looping)

迭代意味着重复执行一段代码多次。主要有三种类型:

1. 计数循环 (FOR)

当你明确知道循环需要运行多少次时使用。

  • 它会自动初始化、检查并增加(或减少)计数器变量。
FOR Counter ← 1 TO 10
    OUTPUT "Loop number: ", Counter
NEXT Counter
2. 前置条件循环 (WHILE)

条件在循环运行之前进行测试。如果条件初始为 FALSE,循环内部的代码将永远不会执行(执行零次)。

WHILE <条件> DO
    <语句>
ENDWHILE
3. 后置条件循环 (REPEAT UNTIL)

条件在循环运行之后进行测试。这保证了循环内部的代码至少会执行一次。循环会一直重复,直到条件变为 TRUE 为止。

REPEAT
    <语句>
UNTIL <条件>

常见错误提醒: WHILE 循环只要条件为 TRUE 就会运行。REPEAT UNTIL 循环会一直运行直到条件变为 TRUE(即:只要条件为 FALSE 就会持续运行)。

8.1.4 (d, e) 求和、计数与字符串处理

(d) 求和与计数

这是循环中常见的两种模式:

  • 计数: 跟踪某事发生的次数。通常将计数变量初始化为 0,每当事件发生时加 1。
    示例:NumberOfStudents ← NumberOfStudents + 1
  • 求和(累加): 保持数值的运行总和。通常将总数变量初始化为 0,每当出现新值时将其加到变量中。
    示例:TotalSales ← TotalSales + CurrentSaleValue

(e) 字符串处理

这些是用于处理文本(STRING 数据)的标准函数。

  • LENGTH(<标识符>): 返回字符串中的字符数。
    示例:LENGTH("Cat") 返回 3。
  • LCASE(<标识符>): 将字符串或字符转换为小写
  • UCASE(<标识符>): 将字符串或字符转换为大写
  • SUBSTRING(<标识符>, <开始位置>, <长度>): 返回字符串的一部分。你需要指定起始位置和要包含的字符数。
    注意:伪代码通常使用 1 作为第一个字符的起始位置,但大纲确认在编程系统中可能使用 0 或 1。请遵循题目中的惯例,如果未指定则使用 1。
    示例:SUBSTRING("Program", 3, 4) 返回 "ogra"。
你知道吗? 在许多编程语言(如 Python)中,字符串索引从 0 开始,而不是 1!但在 IGCSE 伪代码中,除非另有说明,否则通常从 1 开始。

8.1.6 过程、函数与变量作用域

随着程序规模扩大,我们会将它们拆分成更小的、可复用的代码块。

过程与函数

过程(Procedure)和函数(Function)都是可复用的子程序,但它们有一个关键区别:

  • 过程: 一个命名代码块,执行一项任务但不返回值。使用 CALL 关键字调用。
    示例:CALL DisplayMenu()
  • 函数: 一个命名代码块,执行一项任务并必须返回一个值到调用它的地方。它作为表达式的一部分使用。
    示例:Area ← CalculateArea(5, 10)
参数 (Parameters)

参数是传递给过程或函数的值,以便子程序使用。它们充当子程序的输入。

// 定义一个带有一个参数的过程
PROCEDURE Line(Size : INTEGER)
    // ... 使用 Size 的语句 ...
ENDPROCEDURE

// 调用该过程
CALL Line(60)

你可能会接触到最多三个参数的过程和函数。

局部变量与全局变量

作用域 (Scope) 指的是程序中可以访问变量的区域。

  • 全局变量: 在程序最开始(主程序体中)声明。它可以在程序的任何地方访问和修改,包括在过程和函数内部。
  • 局部变量: 在特定的过程或函数内部声明。它只能在该子程序内部使用。一旦子程序执行完毕,局部变量就会被销毁。
    就像是一张只有你自己能读的秘密草稿纸。

为什么要使用局部变量? 它们可以防止意外冲突。如果两个不同的过程都使用名为 i 的变量,只要 i 在各自内部被声明为局部变量,它们就不会产生冲突。

8.1.7 库例程与 8.1.8 可维护的程序

8.1.7 库例程 (Library Routines)

这些是编程环境中包含的预写函数,可以节省你的时间。你需要掌握的主要例程(除了字符串函数、MOD 和 DIV)包括:

  • ROUND(<标识符>, <小数位数>): 将 REAL 数四舍五入到指定的小数位数。
    示例:ROUND(3.14159, 2) 返回 3.14
  • RANDOM(): 返回一个 0 到 1 之间(包含 0,不含 1)的随机 REAL 数。
    若要生成 1 到 10 之间的随机整数:Value ← ROUND (RANDOM() * 10, 0)

8.1.8 创建可维护的程序

可维护的程序是指他人(或以后你自己)容易理解、调试和更新的程序。

关键特性包括:

  • 有意义的标识符: 为变量、常量、过程和函数使用描述性名称(例如,用 MaximumScore 而不是 MS)。
  • 注释: 使用 // 添加备注来解释代码的作用,尤其是复杂的部分。
  • 过程和函数的使用: 将代码拆分为逻辑子部分使主程序流更清晰。
子程序关键要点: 过程执行任务;函数返回数值。始终使用有意义的命名和注释,让你的代码易于维护。

8.2 数组:存储数据列表

8.2.1 数组的声明与使用

数组是一种数据结构,用于存储固定数量的相同数据类型的项,并通过索引(数字)进行访问。

类比:数组就像是一排完全相同的邮箱,每个邮箱都有顺序编号。

1. 一维 (1D) 数组

一维数组是一个简单的列表或向量。

声明:

DECLARE StudentNames : ARRAY[1:30] OF STRING // 30个元素,索引从 1 到 30

使用: 使用方括号 [ ] 访问元素。

StudentNames[1] ← "Ali" // 将 "Ali" 放入第一个位置
OUTPUT StudentNames[5] // 输出位置 5 的值
2. 二维 (2D) 数组

二维数组是列表的列表,通常可视化为表格或网格(行和列)。

声明:

DECLARE Board : ARRAY[1:3, 1:3] OF CHAR // 一个 3x3 的网格(类似于井字棋)

使用: 第一个索引通常是行 (Row),第二个是列 (Column)。

Board[2, 3] ← 'X' // 在第 2 行,第 3 列放入 'X'

8.2.2 & 8.2.3 数组与迭代结合

由于数组索引是连续的数字,数组几乎总是配合迭代(循环)来处理,特别是 FOR 循环

这使你能够系统地读取或写入数组的每个元素。

// 将值写入数组(读取用户输入)
FOR Index ← 1 TO 30
    INPUT StudentNames[Index]
NEXT Index

// 从 2D 数组读取值(需要嵌套迭代)
FOR Row ← 1 TO 3
    FOR Column ← 1 TO 3
        OUTPUT Board[Row, Column]
    NEXT Column
NEXT Row

8.3 文件处理:永久存储

8.3.1 文件的目的

当程序运行时,变量存储在临时的 RAM(主内存)中。当程序关闭时,这些数据就会丢失。
将数据存储在文件中的目的是为了将数据永久保存(在二级存储设备上,如硬盘),以便程序下次运行时可以检索。

8.3.2 文件操作

在伪代码中操作文件,必须遵循特定步骤:

第一步:打开文件 (OPEN)

  • 必须指定模式FOR READ(读取现有数据)或 FOR WRITE(创建新文件或覆盖现有文件)。
  • OPENFILE "Scores.txt" FOR READ

第二步:读取或写入数据 (READ / WRITE)

  • READFILE: 从文件中读取单个数据项或一行文本,并将其存入变量。
  • READFILE "Scores.txt", PlayerName // 读取一个项/行到 PlayerName 中
  • WRITEFILE: 将变量中的单个数据项或一行文本写入文件。
  • WRITEFILE "Scores.txt", NewScore

第三步:关闭文件 (CLOSE)

  • 完成后,必须 CLOSE 文件以确保所有数据正确保存,并且文件不再被其他程序占用。
  • CLOSEFILE "Scores.txt"
文件关键要点: 始终在访问前打开,完成后关闭。如果你使用 FOR WRITE 打开,该文件中之前的所有数据都会丢失!