我正在尝试编写一些示例,以解释何时应使用while循环以及何时应使用for循环。
寻找适合初学者和新手的有趣案例时,我意识到,while循环的绝大多数教科书示例将如下所示:
i = 0
while i < 10:
do something
i = i + 1
“做某事”可能正在打印奇数,对i进行平方等。但是,使用for循环显然可以轻松地编写所有这些代码!
我正在寻找更有趣的示例。他们必须是:
while random() < 0.95
,但这有什么实际用途?)我能想到的唯一例子是当从用户那里获得一个列表输入(例如,要求和的数字)时,但是用户将不得不使用特殊输入来终止它,这似乎毫无意义,因为用户可以提前说出序列中有多少个条目。
答案 0 :(得分:1)
FOR
循环和WHILE
循环之间的根本区别在于,对于FOR
循环,迭代次数受循环开始之前已知的常数限制,而对于WHILE
循环,迭代次数可以是无限的,未知的或无限的。
因此,仅提供WHILE
循环的语言是图灵完备的,而仅提供FOR
循环的语言则不是图灵完成的。
因此,只有WHILE
循环才能做的第一件事就是无限循环。可以轻松地建模为无限循环的事物是例如Web服务器,Netflix客户端,游戏循环,GUI事件循环或操作系统:
WHILE (r = nextHttpRequest):
handle(r)
END
WHILE (p = nextVideoStreamPacket):
frame = decode(p)
draw(frame)
END
WHILE (a = playerAction):
computeNextFrame(a)
END
WHILE (e = nextEvent):
handle(e)
END
WHILE (s = sysCall):
process(s)
END
一个很好的例子是,循环不是无限的,但是事先不知道边界,是(如您在问题中已经提到的)要求用户输入。像这样:
WHILE (askBoolean("Do you want to play again?")):
playGame()
END
另一个很好的例子是处理一个类似C的字符串,其中字符串的长度是未知的,但是是有限的。对于链表或 any 数据结构,情况相同,即“下一个”的概念,但没有“大小”的概念,而是有一些标记以结束(例如,用C中的NUL
终止的字符串)或一种检查是否存在下一个元素的方法(例如,Java中的Iterator
):
WHILE ((element = getNext()) != END_MARKER):
process(element)
END
WHILE (hasNextElement):
process(getNext())
END
在某些情况下,可以使用FOR
循环来处理 ,但是WHILE
循环更优雅。我可以想到的一种情况是,迭代次数的界限是预先知道的,它是恒定的,但是已知界限非常大,而实际需要的迭代数目显着小于该界限。
不幸的是,我无法提出一个现实的例子,也许有人可以。这样一来,FOR
循环通常看起来像这样,以便从实际的迭代次数一直跳到上限:
FOR (i FROM 1 TO $SOME_LARGE_UPPER_BOUND):
IF (terminationConditionReached):
NOOP()
ELSE:
doSomethingInteresting()
END
END
最好用
表示WHILE (NOT terminationConditionReached):
doSomethingInteresting()
END
如果FOR
的值值得关注,在这种情况下使用i
循环 可能是合理的:
FOR (i FROM 1 TO $SOME_LARGE_UPPER_BOUND):
IF (terminationConditionReached):
NOOP()
ELSE:
doSomethingInterestingWithI(i)
END
END
我可以想到的最后一种情况是,即使迭代次数受已知常数限制,WHILE
循环比FOR
循环更合适。对于循环来说“非常有趣”。
例如,井字游戏循环最多只需要9步,因此可以将其建模为FOR
循环:
FOR (i FROM 1 TO 9):
IF (player1Won OR player2Won):
NOOP
ELSE:
makeMove()
END
END
但是,数字“ 9”在这里并不是很有趣。有趣的是,一个玩家拥有一个玩家,还是一个棋盘已满:
WHILE (NOT (player1Won OR player2Won OR boardFull)):
makeMove()
END
[注意:至少如果与孩子玩游戏时,这也是倒数第二个例子,即已知上限为9,但是很多游戏会少于9步。但是,我仍然想找到一个示例,这也不是一个语义上不有趣的终止条件的示例。]
因此,在这里,我们有两种情况:一种,无法使用FOR
循环 (当边界未知,不存在或无限时),以及一种,其中可以使用FOR
循环,但是WHILE
循环更能实现意图揭示。