循环和while语句简介
本节阅读量:循环简介
现在真正的乐趣开始了——在下面课程中,我们将讨论循环。循环允许一段代码重复执行,直到满足某个条件退出。循环为编程添加了大量的灵活性。
例如,假设您希望打印1到10之间的所有数字。如果没有循环,您可能尝试如下操作:
|
|
虽然这是可行的,但随着想打印更多的数字,这越来越困难:如果您想打印1到1000之间的所有数字,该怎么办?那将是相当多的代码量!但这样的程序是可以这样硬写的,因为在编译时知道要打印多少个数字。
现在,让我们稍微改变一下需求。如果我们想让用户输入一个数字,然后打印1和用户输入的数字之间的所有数字,该怎么办?用户将输入的数字在编译时不可知。该如何解决这个问题呢?
While语句
while语句(也称为while循环)是C++提供的三种循环类型中最简单的一种,它的定义与if语句的定义非常相似:
|
|
使用while关键字声明while语句。执行while语句时,将计算条件表达式。如果条件的计算结果为true,则执行关联的语句。
然而,与if语句不同,一旦语句完成执行,控制权就会返回到while语句的顶部,并且重复该过程。这意味着只要条件继续计算为true,while语句就会保持循环。
让我们来看一个简单的while循环,它打印从1到10的所有数字:
|
|
输出:
|
|
让我们仔细看看这个程序在做什么。
首先,我们定义了一个名为count的变量,并将其设置为1。条件计数<=10为true,因此执行该语句。在这种情况下,对应的语句是一个代码块,因此块中的所有语句都将执行。块中的第一条语句打印1和空格,第二条语句将计数增加到2。现在返回到while语句的顶部,并再次计算条件。2<=10的计算结果为true,因此再次执行代码块。循环将重复执行,直到计数为11,此时11<=10的计算结果将为false,并且将跳过与循环关联的语句。此时,循环完成。
虽然这个程序比键入1到10之间的所有数字稍微多一些代码,但考虑一下修改程序以打印1到1000之间的所有数是多么容易:需要做的只是将计数<=10更改为计数<=1000。
初始条件计算为false的语句
请注意,如果条件最初的计算结果为false,则关联的语句将根本不会执行。考虑以下程序:
|
|
条件表达式 15 <= 10 的计算结果为false,因此跳过关联的语句。程序继续,打印的唯一内容是“done!”。
死循环(无限循环)
另一方面,如果表达式的计算结果总是为true,则while循环将永远执行。这称为死循环。下面是示例:
|
|
由于count在此程序中从不递增,因此count <= 10将始终为true。因此,循环永远不会终止,程序将永远打印11111。
有意的死循环
可以这样声明有意的死循环:
|
|
退出无限循环的唯一方法是通过return语句、break语句、exit语句、goto语句、引发异常或用户终止程序。
下面是一个愚蠢的例子,来演示这一点:
|
|
该程序将持续循环,直到用户输入n作为输入,此时if语句将求值为true,并返回0;将导致函数main() 退出,终止程序。
在连续运行并为web请求提供服务的web服务器应用程序中,经常会看到这种循环。
最佳实践
对于有意的无限循环,使用 while (true)。
循环变量的命名
循环变量是用于控制循环执行次数的变量。例如,给定while ( count <= 10 ),count是一个循环变量。虽然大多数循环变量的类型都是int,但您偶尔会看到其他类型(例如char)。
循环变量通常被赋予简单的名称,其中i、j和k是最常见的。
然而,如果您想知道在程序中的何处使用循环变量,并且在i、j或k上使用搜索函数,则搜索函数将返回程序中大半的行!由于这个原因,一些开发人员更喜欢独特的循环变量名,如iii、jjj或kkk。由于这些名称更独特,这使得搜索循环变量变得更容易,并帮助它们作为循环变量脱颖而出。一个更好的想法是使用“真实”的变量名,例如count、index,或者提供有关计数内容的更多细节的名称(例如userCount)。
最常见的循环变量类型称为计数器,它是一个循环变量,用于统计循环已执行的次数。在上面的示例中,变量count是一个计数器。
作为旁白…
使用i、j和k作为循环变量名是因为这是Fortran编程语言中整形变量的前三个最短名称。该公约自那时以来一直存在。
整形循环变量应该有符号
整形循环变量几乎总是有符号的,因为无符号整数可能会导致意外的问题。考虑以下代码:
|
|
看看上面的例子,看看您是否可以发现错误。如果你以前没有看到过,这不是很明显。
事实证明,这个程序是一个无限循环。它从打印“10 9 8 7 6 5 4 3 2 1 blastoff!”这符合预期,但随后循环变量计数溢出,并从4294967295开始倒计时(假设为32位整数)。为什么?因为循环条件计数>=0永远不会为false!当计数为0时,0>=0为真。然后执行–count,count回绕到4294967295。由于4294967295>=0为真,因此程序继续。因为count是无符号的,所以它永远不能是负的,并且因为它永远不能为负,所以循环不会终止。
最佳实践
整形循环变量通常应为有符号整数。
每N次迭代执行一次操作
每次执行循环时,它被称为一次迭代。
通常,我们希望在第2、3或4次迭代中执行某些操作,例如打印换行。通过在计数器上使用余数运算符,可以轻松完成此操作:
|
|
该程序生成结果:
|
|
嵌套循环
还可以将循环嵌套在其他循环的内部。在下面的示例中,嵌套循环(我们称之为内部循环)和外部循环都有自己的计数器。注意,内部循环的循环表达式也使用了外部循环的计数器!
|
|
该程序打印:
|
|
嵌套循环对于新程序员来说往往很难理解,如果您发现这有点令人困惑,请不要气馁。对于外部循环的每个迭代,外部循环的主体都执行一次。由于外循环体包含内循环,因此对外循环的每次迭代都执行内循环。
让我们更详细地研究一下这是如何工作的。
首先,我们有一个外循环(具有循环变量outer),它将循环5次(outer依次具有值1、2、3、4和5)。
在外部循环的第一次迭代中,outer具有值1,然后执行外部循环体。在外循环的主体内部,有另一个循环,包含循环变量inner。内部循环从1迭代到outer(值为1),因此该内部循环将执行一次,打印值1。然后打印一个换行,并将外部增量增加到2。
在外部循环的第二次迭代中,outer具有值2,然后执行外部循环体。在外部循环的主体内部,inner从1迭代到outer(现在值为2),因此该内部循环将执行两次,打印值1和2。然后打印一个换行,并将outer增加到3。
该过程继续,在连续的过程中内环打印1 2 3、1 2 3 4和1 2 3 4 5。最终,outer增加为6,并且由于外部循环条件(outer <= 5)为false,因此外部循环完成。然后程序结束。
如果您仍然感到困惑,请在调试器中逐行遍历该程序,并观察inner和outer的值,这是更好地理解正在发生的事情的好方法。
