跳到正文
IGCSE·Tuition

计算机科学 · 常见难点

我的循环停不下来,或漏掉最后一项

循环读起来没问题,却要么永远结束不了,要么悄悄漏掉最后一个值。

本页内容
  1. 停不下来的循环长什么样?
  2. 怎样修正?
  3. 漏掉最后一项的循环长什么样?
  4. 怎样修正差一错误?
  5. 分辨是哪一种错误
  6. 任何循环都适用的检查清单
  7. 接下来看什么
  8. 当追踪还不够的时候

停不下来的循环,是因为条件永远不会变成假。漏掉最后一项的循环,是提前一轮就停了。两者最快的发现方法,都是手动追踪循环,每一轮一行。

本页为每一种情况各给一个完整例子、一个修正版本和一份简短的检查清单。这里的记法是简单易读的伪代码。你的试卷可能使用特定风格,请对照考纲确认适用的路线。

停不下来的循环长什么样?

看这个算法。它本意是每次减 3,倒数到零。

Num ← 10
WHILE Num <> 0
    Num ← Num - 3
ENDWHILE
OUTPUT "Done"

追踪它,并每次写出条件的结果。

第几轮开始时的 NumNum <> 0 ?结束时的 Num
110真7
27真4
34真1
41真−2
5−2真−5

Num 依次是 10、7、4、1、−2、−5,永远不会刚好等于 0。“不等于 0”这个测试一直为真,所以永远到不了 “Done”。

怎样修正?

把条件改成:当数值越过目标时就停止,而不只是刚好等于目标时才停。

Num ← 10
WHILE Num > 0
    Num ← Num - 3
ENDWHILE
OUTPUT Num

追踪:10 → 7 → 4 → 1 → −2。第四轮之后 Num 是 −2,而 −2 > 0 为假,所以循环停止。输出是 −2。

值得养成的习惯:当数值以固定步长变化时,优先使用大于或小于的条件,除非你已经证明步长刚好会落在目标上。

漏掉最后一项的循环长什么样?

下面是一个有五个分数的数组(array),这个例子里索引从 1 数到 5。任务是把它们全部加起来。

Scores = [12, 7, 15, 9, 10]

Total ← 0
FOR i ← 1 TO 4
    Total ← Total + Scores[i]
NEXT i
OUTPUT Total
iScores[i]相加后的 Total
11212
2719
31534
4943

输出是 43,但真正的总和是 12 + 7 + 15 + 9 + 10 = 53。循环在 4 停下,所以 Scores[5] = 10 从未被加上。差值 53 − 43 = 10 正好是漏掉的那一项,检查自己的答案时,这是个有用的线索。

怎样修正差一错误?

让循环的最后一个值等于数组的最后一个索引。

Total ← 0
FOR i ← 1 TO 5
    Total ← Total + Scores[i]
NEXT i
OUTPUT Total

追踪:12、19、34、43、53。输出 53。✓

如果数组长度可能改变,就用它的长度而不是固定的 5,例如 FOR i ← 1 TO Length,其中 Length 存放项目个数。

分辨是哪一种错误

症状可能原因先检查什么
程序永远结束不了条件永远不会变成假循环有没有改变条件用到的变量?
会停,但答案少了一项上限少一,或用了 < 而不是 <=在循环旁写出第一个和最后一个索引
结尾时崩溃或报错上限多一,读取到数组之外最后一个索引在范围内吗?
5 个项目能用,1 个或 0 个就出错循环假设至少有两个项目手动测试最小的情况

任何循环都适用的检查清单

  1. 写出循环应该处理的第一个和最后一个值。
  2. 完整追踪第一轮和最后一轮。
  3. 问:什么会让条件变成假?检查循环是否朝着那个方向前进。
  4. 用空列表或只有一个项目来测试。
  5. 检查结果是否合理,例如换一种方式把列表加一遍。

受限伪代码追踪训练器让你逐步查看原创算法,看到每个分支和循环的决定,前提是你的路线允许。安全的 Python 推理沙盒会进行有限制的运行,循环跑太久时会被停止。

接下来看什么

完整的概念请读循环与数组。边界错误另有专页:我的程序能运行,但在边界情况失败。然后试试原创练习里的混合题,整体地图见学习指南。

当追踪还不够的时候

有些同学追踪得很仔细,仍然看不出循环哪里出错,因为背后的想法,例如“变量会自己更新”,在纸上是看不见的。看着你把想法说出来,就很容易找到它。在线一对一 Computer Science 补习从一小时的付费试听课开始,费用按所安排老师确认的价格计算,RM80 起。

常见问题

为什么我的 WHILE 循环停不下来?

条件永远不会变成假。通常是条件里用到的变量没有在循环内被改变,或者改变的方式跳过了停止值,例如每次减 3,却在等它刚好等于 0。手动追踪三轮,看看条件每次看到的是什么。

为什么我的循环漏掉最后一项?

这是差一错误(off-by-one)。循环提前一步停止,例如上限少了一,或该用 <= 的地方用了 <。用手写出第一个和最后一个索引,再检查循环是否走过这两个。

数组从 0 还是从 1 开始?

这取决于你的考试路线所用的记法和语言。有些伪代码例子从 1 开始数,Python 则从 0 开始。请查看你的代码和年份对应的 Cambridge 考纲,并在写循环之前,先在演算旁写出第一个和最后一个索引。

怎样不运行就测试一个循环?

用追踪表。每个变量一栏,每一轮一行,并在每行旁边写出条件的结果。如果某一行没有改变条件所依赖的值,你在运行之前就已经找到了无限循环。

资料来源

  1. Cambridge IGCSE Computer Science 0478 syllabus page

更新于:

下一步

如果循环错误修好之后又反复出现,一对一的老师可以看着你追踪,找出背后的习惯。

一小时付费试听课,按所安排老师确认的收费,RM80 起。 其他费用、时间安排及后续课程,在试听课后由你与老师直接确认。

已通过我们的服务帮助 9,000+ 名学生