3.3 循环结构

3.3 循环结构

让我们从下面的编程做起,体会循环结构的流程。

【例3.8】需求:输出从1累加到10的累加和。

分析:需要有一个变量sum,保存每次累加的结果,初值为0;需要有一个变量i,保存每次累加的那个加数,初值为1。只要加数i不超过10,就循环执行:加数累加入sum时,加数i自增1。当循环退出时,sum中保存的就是从1累加到10的累加和。

做法1的流程如图1.3.7所示。

图1.3.7 做法1

【代码3.8.1】做法1

代码3.8.1

第8行是循环语句while,控制语句从第8行到第11行循环执行,每次都先判断i<=10是否为真,如果为真,则执行一遍下面的循环体。一直循环,直到i<=10为假时,退出循环,执行循环语句后面的第13行语句。

while语句后面的循环条件必须写在小括号中,对于后面的循环体,如果语句多于一条,则必须写在大括号中。

【代码3.8.2】做法2

代码3.8.2

第8行是循环语句for,控制语句从第8行到第11行循环执行。在for后面的小括号中,第一个分号前面是循环之前只执行一次的语句,这里是i赋初值为1;两个分号之间的i<=10是在每次循环之前要判断的循环条件,当条件为真时,执行一遍下面的循环体;第二个分号之后的i++是每次执行完一遍循环体后就执行一次的内容,这里是i自增1。第9行到第11行就是循环体。

for后面一定需要有一对小括号,小括号中必须有两个分号,这两个分号将小括号中的语句分隔为三部分:第一部分是循环之前只执行一次的语句,一般用于赋初值;第二部分是每次首先要进行的逻辑判断条件,当条件为真时,就执行一次循环体,直到条件为假,退出循环;第三部分是每次执行一次循环体后都要执行一次的语句,一般用于循环变量的递增(或者递减)。

做法3的流程如图1.3.8所示。

图1.3.8 做法3

【代码3.8.3】做法3

代码3.8.3

第7行是循环语句do-while,do后面大括号中的是循环体,首先执行一遍循环体,然后判断while后面小括号中的条件(第10行中的i<=10),如果条件为真,则再执行一遍循环体,如此循环,直到条件为假,退出循环。

do-while循环是第一次不判断循环条件,在循环体首先执行一次后再判断循环条件,如果条件为真,则执行一次循环体,直到循环条件为假,退出循环。do-while循环的循环体至少会被执行一次。

【例3.9】需求:求1-2+3-4+5-6+…-10的结果。

分析:“1-2+3-4+5-6+…-10”可以看作是1到10的累加,只是每一项都乘以一个符号位,每一项的符号位是前一项的符号位变反(乘以-1)。符号位的初值是-1,这样首次变反之后是+1,也就是第一项的符号位为+1。

【代码3.9】

代码3.9

【例3.10】需求:输入一个正整数,求这个整数的各位数字之和。

分析:当一个整数的位数不确定的时候,怎样取到它的每一位数字?需要设计统一的算法,要求算法对任意位数的整数都适用。任意位数的整数除以10的余数一定是个位数字,这样就可取到个位数字;任意位数的整数除以10的商,就去掉了个位数字,如256/10等于25。不断循环这两步,就可以依次取到个位,十位,百位,…。

【代码3.10】

代码3.10

【例3.11】需求:输出九九乘法表(如图1.3.9所示)。

图1.3.9 九九乘法表

分析:观察九九乘法表的规律,它一共有9行,每一行的每个算式乘号左边的数字都相同,分别是行号(从1到9);每一行的每个算式乘号右边的数字可以看作列号,总是从1循环到行号。

【代码3.11】

代码3.11

【例3.12】需求:求满足n!小于1 000的最大的n。

分析:n!等于(n-1)!·n,每次循环将前一项(i-1)的阶乘乘以i,就是i的阶乘。注意当阶乘超过1 000而退出循环时,满足阶乘小于1 000的i应该是i-1。

【代码3.12.1】

代码3.12.1

也可以用另一种方法实现,在循环体中用break退出循环。

【代码3.12.2】

【例3.13】需求:打印100以内的素数。

分析:最小的素数是2,从2开始循环到100,依次判断每个数是否是素数,如果是素数,就输出。

对于从2到100之间的任何一个数i,要判断i是否是素数,需要依次用从2到i-1之间的数去除以i,如果全都没有除尽(退出循环的时候,除数和i相等),则说明i是素数;如果有任何一个除数除尽了,则说明i不是素数。

当然,根据素数的判断定理,要判断i是否素数,只需要用从2到去除以i,如果都没有除尽,那i就是素数,下面的程序没有利用这个定理。

【代码3.13.1】第一种方法

代码3.13

第10行的break语句表示退出break语句所在的第3行的for循环。

【代码3.13.2】第二种方法(用到continue语句)

continue语句表示结束本次循环,进入下一次循环。在代码3.13.2中,当执行到第12行的continue时,当次循环余下的第14行就不执行了,此时程序转至第8行,进入下一次循环。

循环结构的语法总结如下。

(1)while语句

先判断布尔表达式的值,如果值为true,则执行一遍循环体,循环以上步骤,直到布尔表达式的值为false时,就不再执行循环体,退出循环,然后接下去执行后面的语句。

(2)do-while语句

先执行一遍循环体,然后判断布尔表达式的值,如果值为true,则再执行循环体一遍,循环以上步骤,直到布尔表达式的值为false时,就不再执行循环体,退出循环,然后接下去执行后面的语句。

do-while与while的区别是do-while至少会执行一遍循环体。

(3)for语句

for后的小括号中的语句由两个分号分为三部分:第一部分只在循环语句之前执行一次(一般是进行初始化);第二部分是布尔表达式,每次判断布尔表达式的值,如果值为true,则执行循环体一遍,如果值为false,则退出循环,接下去执行循环后面的语句;第三部分在每次执行完一遍循环体之后执行一次(一般是每次进行的更新)。因此for小括号中的三部分内容也可以改变位置。例如,求1累加到10的和的程序写法有如下三种。

写法1:

写法2:

写法3:

以上写法是等价的,不过写法1是for语句的常用写法,是比较紧凑的。当for小括号中的第一或者第三部分不只是一个语句时,多个语句要用逗号隔开。例如,

(4)break语句

跳出break语句所在的switch语句或者循环语句。

(5)continue语句

本次循环余下的语句被跳过,直接进入下次循环。