使用while循环的简单示例

时间:2018-09-08 08:43:25

标签: language-agnostic

我正在尝试编写一些示例,以解释何时应使用while循环以及何时应使用for循环。

寻找适合初学者和新手的有趣案例时,我意识到,while循环的绝大多数教科书示例将如下所示:

i = 0
while i < 10:
    do something
    i = i + 1

“做某事”可能正在打印奇数,对i进行平方等。但是,使用for循环显然可以轻松地编写所有这些代码!

我正在寻找更有趣的示例。他们必须是:

  1. 适合年轻的程序员(例如,不需要太多数学运算,例如数字根查找或Collat​​z猜想中的序列)
  2. 使用while循环而不是for可以更轻松(或更直观)地解决问题。
  3. 它有一些实际用途(例如,我可以做while random() < 0.95,但这有什么实际用途?)

我能想到的唯一例子是当从用户那里获得一个列表输入(例如,要求和的数字)时,但是用户将不得不使用特殊输入来终止它,这似乎毫无意义,因为用户可以提前说出序列中有多少个条目。

1 个答案:

答案 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循环更能实现意图揭示。