选择循环的种类
在大多数语言中,你只能用到少数几个循环:
- 计数循环执行的次数是一定的,可能是针对每位雇员执行一次;
- 连续求值的循环预先并不知道将要执行多少次,它会在每次迭代时检查是否应该结束;
- 无限循环一旦启动就会一直执行下去;
- 迭代器循环对容器内的每个元素执行一次操作。
什么时候使用while循环
如果你预先并不知道循环要迭代多少次,那么就使用while循环。
- 检测位于循环的开始;
- 检测位于循环的结尾。
什么时候用带退出的循环
带退出的循环就是终止条件出现在循环中间而不是开始或者末尾的循环。
- 正常的带推出循环;
- 非正常的带推出循环。
何时使用for循环
如果你需要一个执行次数固定的循环,那么for循环就是一个很好的选择。
何时使用for each循环
for each循环或其等价物很适用于对数组或者其他容器的各项元素执行操作。
循环控制
- 进入循环:
- 只从一个位置进入循环;
- 把初始化代码紧放在循环前面;
- 用while(true)表示无限循环;
- 在适当的情况下多使用for循环;
- 在while循环更适用的时候,不要使用for循环。
- 处理好循环体:
- 用“{”和“}”把循环中的语句括起来;
- 避免空循环;
- 把循环内务操作要么放在循环的开始,要么放在循环的末尾;
- 一个循环只做一件事。
- 退出循环:
- 设法确认循环能够终止;
- 使循环终止条件看起来很明显;
- 不要为了终止循环而胡乱改动for循环的下标;
- 避免出现依赖于循环下标最终取值的代码;
- 考虑使用安全计数器。
- 提前退出循环:
- 考虑在while循环中使用break语句而不用布尔标记;
- 小心那些有很多break散布其中的循环;
- 在循环开始处用continue进行判断;
- 如果语言支持,请使用带标号的break结构;
- 使用break和continue时要小心谨慎。
- 检查端点;
- 使用循环变量:
- 用整数或者枚举类型表示数组和循环的边界;
- 在嵌套循环中使用有意义的变量名来提高可读性;
- 用有意义的名字来避免下标串话;
- 把循环下标变量的作用域限制在本循环内。
- 循坏长度:
- 循环要尽可能地短,以便能够一目了然;
- 把嵌套限制在3层以内;
- 把长循环的内容移到子程序里;
- 要让长循环格外清晰。
轻松创建循环——由内而外
从一种情况开始,用字面量来编写代码。然后缩进它,在外面加上一个循环,然后用循环下标或计算表达式替换那些字面量。如果需要,在它的外面再套上一个循环,然后用循环下标或计算表达式替换那些字面量。根据你的需要持续这一过程。等你做完后,再加上所需要的初始化。由于你是从简单的情况开始并且由内而外生成代码的,因此你可以把这一过程看作是由内而外的编码。
循环和数组的关系
循环和数组之间有着密切的联系。在许多情况中,循环就是用来操纵数组的,而且循环计数器和数组下标一一对应。
核对表:循环
循环的创建和选择
- [ ] 在合适的情况下用while循环取代for循环了吗?
- [ ] 循环式由内到外创建的吗?
进入循环
- [ ] 是从循环头部进入循环的吗?
- [ ] 初始化代码是直接位于循环前面的吗?
- [ ] 循环是无限循环或者事件循环吗?它的结构是否清晰?
- [ ] 避免使用像
for i = 1 to 9999
这样的代码吗? - [ ] 如果这是一个C++、C或Java中的for循环,那么把循环头留给循环控制代码了吗?
循环的内部
- [ ] 循环是否用了
{ }
或其他等价物来括上循环体,以防止因修改不当而出错吗? - [ ] 循环体内有内容吗?它是非空的吗?
- [ ] 把内务处理集中地放在循环开始或者循环结束处了吗?
- [ ] 循环足以一目了然吗?
- [ ] 循环嵌套层次不多于3层吗?
- [ ] 把长循环的内容提取成单独的子程序吗?
- [ ] 如果循环很长,那么它非常清晰吗?
循环下标
- [ ] 如果这是一个for循环,那么其中的代码有没有随意修改循环下标值?
- [ ] 是否把重要的循环下标值保存在另外的变量里,而不是在循环体外使用该循环下标?
- [ ] 循环下标是序数类型(整数)或者枚举类型——而不是枚举类型吗?
- [ ] 循环下标的名字有意义吗?
- [ ] 循环避免了下标的串话问题吗?
退出循环
- [ ] 循环在所有可能的条件下都能终止吗?
- [ ] 如果你建立了某种安全计数器标准,循环使用安全计数器了吗?
- [ ] 循环的退出条件清晰吗?
- [ ] 如果使用了break或者continue,那么他们用对了吗?
要点
- 循环很复杂。保持循环简单将有助于别人阅读你的代码。
- 保持循环简单的技巧包括:避免使用怪异的循环、减少嵌套层次、让入口和出口一目了然、把内务操作代码放在一处。
- 循环下标很容易被滥用。因此命名要准确,并且要把他们各自仅用于一个用途。
- 仔细地考虑循环,确认它在每一种情况下都运行正常,并且在所有可能的条件下都能退出。