在计算机科学和编程教学中,循环通常按“如何决定何时停止”来分类。主要有以下几种经典类型:
| 类型 | 英文名 | 中文名 | 特点 | 示例 |
|---|---|---|---|---|
| 1. 计数控制循环 | Counter-controlled loop | 计数器循环 | 循环次数已知,靠计数器控制 | for i in range(5) |
| 2. 哨兵控制循环 | Sentinel-controlled loop | 哨兵循环 | 用一个特殊值(哨兵)表示结束 | 空行、-1、"quit" |
| 3. 标志控制循环 | Flag-controlled loop | 标志循环 | 用布尔变量控制是否继续 | while not done: |
| 4. EOF 控制循环 | EOF-controlled loop | 文件结束循环 | 读到文件/流末尾时停止 | while (line = f.readline()) |
| 5. 用户确认循环 | User-confirmation loop | 用户确认循环 | 每次问用户“还要继续吗?” | "继续?(y/n)" |
for item in list 或 while True + break,弱化了传统分类。“哨兵”这个词本身有点抽象
-1 表示年龄输入结束,-1 就是哨兵。中文教学中常省略术语
很多中文教程只说:
“用 while 循环读到空行为止”
而不提背后的分类概念,导致你知道怎么写,但不知道叫什么。
| 《程序设计基础(C语言)》 |
循环按“如何知道该停了”分为: 1. 数到 n 就停 → 计数器循环(for) 2. 看到特殊值就停,直接依赖于输入值 → 哨兵循环(while + sentinel) 3. 某个开关关了就停,循环使用一个独立的布尔标志 → 标志循环(while not done) 4. 数据没了就停 → EOF 循环
Sentinel-controlled loop(哨兵控制循环):使用一个特殊的“哨兵值”(sentinel value)来标记循环的结束。这个哨兵值通常不是一个有效的业务数据,而是专门用于控制循环终止的标记。例如,在输入过程中,用户输入一个特定值(如空字符串、-1等)来表示输入结束。
data = input("请输入一组人员的姓名、性别、年龄:")
while data:
# 处理数据
data = input("请输入一组人员的姓名、性别、年龄:")
循环条件直接依赖于输入变量 data。
当用户输入空字符串(直接按回车)时,data 变为空字符串,在布尔上下文中被视为 False,循环终止。
空字符串在这里充当了哨兵值,因为它不是一个有效的业务数据(有效的输入应包含姓名、性别、年龄),而是专门用于标记输入结束的特殊值。
因此,这个循环是 Sentinel-controlled loop。
Flag-controlled loop(标志控制循环):使用一个独立的布尔变量(标志)来控制循环的执行。循环条件依赖于这个标志变量的状态,而不是直接依赖于输入值。
flag = True
while flag:
data = input("...")
if data == "":
flag = False
else:
# 处理数据