第 8.2 章:数组——整理你的数据
你好,IGCSE 计算机科学同学们!数组听起来可能很复杂,但它们是你编程学习过程中最实用的工具之一。
你可以把数组想象成一个井井有条的文件柜,或者一组贴了标签的储物柜。与其创建成百上千个独立的变量(如 Student1、Student2、Student3……),不如将所有相关的数据归类在同一个名称下。这会让处理大量信息变得更加快速且简单。
在本章中,我们将学习如何声明这些结构化的存储容器(数组),以及最关键的一点:如何利用循环(迭代)来填充和读取它们。
1. 理解数组的基本概念
什么是数组?
数组是一种编程中常用的数据结构,用于存储固定数量的、相同数据类型的元素。
- 固定长度 (Fixed Length): 一旦创建了数组,你就定义了它的大小,且在程序运行时,该大小通常无法更改。
- 同质数据 (Homogeneous Data): 数组中存储的所有项(称为元素)必须是相同的数据类型(例如,全为整数 INTEGER 或全为字符串 STRING)。
关键术语:索引和元素
要从数组中获取信息(或将信息存入),你需要知道它的位置。我们使用索引 (Index)(也称为下标)。
类比:想象有一排 10 个学生储物柜。数组就是这一排储物柜,而索引就是写在每个储物柜门上的数字(1, 2, 3, ... 10)。储物柜里的物品就是元素。
- 元素 (Element): 存储在数组某个槽位中的实际数据。
- 索引 (Index): 用于访问特定元素的位置编号。
关于索引的重要说明(教学大纲 8.2): 在计算机科学中,索引可以从 0 开始(从 0 开始计数),也可以从 1 开始(从 1 开始计数)。对于 IGCSE 伪代码,除非另有说明,我们通常默认采用从 1 开始的索引,但请注意,某些编程语言是从 0 开始计数的。声明语法允许你明确设置起始(下界)和结束(上界)索引。
快速回顾:数组属性
Array (数组):All items (所有项目) 必须是 Alpha (相同的) 数据类型。
Remember (记住):大小是 Rigid (刚性的/固定的)。
Read/write (读/写):使用 Row (行) 号(索引)来读写数据。
2. 一维 (1D) 数组 (8.2.1)
一维数组是最简单的类型。它以单行或列表的形式存储数据。
第一步:声明一维数组
声明一维数组时,必须明确三点:数组名称、索引范围(下界:上界)以及元素的数据类型。
伪代码语法:
DECLARE <标识符> : ARRAY[<下界>:<上界>] OF <数据类型>
示例:声明一个名为 TestScores 的数组来存储 50 个 INTEGER 值。索引范围为 1 到 50。
DECLARE TestScores : ARRAY[1:50] OF INTEGER
第二步:访问和赋值(使用变量作为索引)
要读取或写入特定元素,你需要使用数组名称,并在方括号 [ ] 中填入索引号。
为了让代码更灵活,在循环结构(8.2.2)中,你应该始终使用变量(如 i 或 Index)作为索引。
访问示例:
OUTPUT TestScores[5] // 显示存储在第 5 个位置的分数
赋值示例:
TestScores[12] ← 95 // 将第 12 个位置的分数设置为 95
第三步:使用迭代(循环)进行读取和写入 (8.2.3)
由于数组连续存储了许多元素,我们通常会使用循环(迭代)来高效地处理它们。计数控制循环(FOR 循环)非常适合此场景,因为我们确切地知道需要重复过程的次数(即数组的大小)。
示例:填充一维数组
此段伪代码通过 50 次询问用户输入,填充 TestScores 数组(大小为 50)。
DECLARE TestScores : ARRAY[1:50] OF INTEGER
DECLARE Counter : INTEGER
FOR Counter ← 1 TO 50
OUTPUT "Enter score number ", Counter
INPUT TestScores[Counter] // Counter 被用作索引变量
NEXT Counter
要点总结(一维数组)
一维数组就是列表。我们使用单一变量作为索引,并且通常使用一个 FOR 循环来管理整个列表的数据录入或读取。
3. 二维 (2D) 数组 (8.2.1)
如果说一维数组像列表,那么二维数组就更像一张表格或一个电子表格。它有两个维度:行和列。
类比:想象一个教室的座位表。数据(学生姓名)由其行号和列号定位。
第一步:声明二维数组
声明二维数组时,必须指定两个维度的索引范围:行和列。
伪代码语法:
DECLARE <标识符> : ARRAY[<L1>:<U1>, <L2>:<U2>] OF <数据类型>
-
L1:U1指的是行的索引范围(第一个维度)。 -
L2:U2指的是列的索引范围(第二个维度)。
示例:声明一个名为 Board 的数组来表示 8x8 的国际象棋棋盘(字符类型)。
DECLARE Board : ARRAY[1:8, 1:8] OF CHAR
第二步:访问二维数组中的元素
要访问元素,你需要在方括号内提供两个索引值,并用逗号隔开。习惯上,我们使用 [行, 列] 的格式。
访问示例:
OUTPUT Board[2, 5] // 显示存储在第 2 行、第 5 列的字符
赋值示例:
Board[8, 1] ← 'R' // 将第 8 行、第 1 列的元素设置为 'R'(车)
第三步:使用嵌套迭代处理二维数组 (8.2.3)
由于二维数组是一个网格,要读取或写入*整个*数组的数据,需要使用嵌套循环(循环中嵌套另一个循环)。
- 外层循环通常控制行。
- 内层循环控制该特定行中的列。
示例:初始化二维棋盘数组
此段伪代码将 8x8 的 Board 数组全部初始化为空格 (' ')。
DECLARE Board : ARRAY[1:8, 1:8] OF CHAR
DECLARE RowIndex : INTEGER
DECLARE ColIndex : INTEGER
FOR RowIndex ← 1 TO 8
FOR ColIndex ← 1 TO 8
Board[RowIndex, ColIndex] ← ' '
NEXT ColIndex
NEXT RowIndex
嵌套循环步骤解析:
RowIndex从 1 开始。- 内层循环
ColIndex完整运行(1, 2, 3, 4, 5, 6, 7, 8)。它设置从Board[1, 1]到Board[1, 8]的值。 - 内层循环结束。
- 外层循环移动到
NEXT RowIndex(现在为 2)。 - 内层循环再次完整运行(1 到 8)。它设置从
Board[2, 1]到Board[2, 8]的值。 - 此过程重复,直到
RowIndex达到 8。
要点总结(二维数组)
二维数组就是表格。我们使用两个索引变量(一个用于行,一个用于列),并且需要嵌套循环(通常是两个 FOR 循环)来处理每一个元素。
4. 常见错误与记忆技巧
当心数据类型不匹配!
如果你声明数组为 OF INTEGER,你就不能尝试在其中存储 STRING 或 BOOLEAN 类型的值。
错误示例:
DECLARE Ages : ARRAY[1:10] OF INTEGER
Ages[3] ← "Twenty-One" // 错误:尝试将 STRING 存入 INTEGER 数组。
“差一错误” (Off-By-One Error,程序员的噩梦)
这发生在你的循环运行次数比数组大小多一次或少一次时。
示例: 如果你的数组声明为 ARRAY[1:10],它有 10 个槽位(1 到 10)。如果你写了一个 FOR i ← 0 TO 9 的循环,你将访问到错误的槽位(如果索引 0 无效,程序甚至会崩溃)。
提示: 务必使循环界限与数组边界精确匹配。
DECLARE Names : ARRAY[1:10] 需要配合 FOR i ← 1 TO 10 使用。
你知道吗?数组与 RAM
当计算机为数组分配内存时,它会预留一块单一的、连续的内存区域,大小足以容纳*所有*元素。这就是为什么数组访问速度非常快的原因;计算机可以根据起始地址和索引号,准确地算出每个元素所在的位置。
数组学习核对清单
- 声明: 定义名称、边界(起始和结束索引)以及数据类型。
-
访问: 使用方括号
[ ]配合索引(二维数组使用两个索引)。 - 处理: 使用循环(迭代)。一维数组使用单个 FOR 循环,二维数组使用嵌套 FOR 循环。
- 灵活性: 在循环内部访问元素时,务必使用变量(如计数器或循环索引)。