第3章 流程控 制 前面介绍的程序都是一条一条语句顺序执行的。程序中的每一条语句都执行一次, 而且只能执行一次,这些语句的组织方式称为顺序结构。只使用顺序结构不能解决所有 问题,为满足特定情况的需要,常常需要改变程序的顺序流程。计算机科学家为结构化程 序定义了三种流程结构:顺序结构、选择结构和循环结构(1所示)。 如图3. 图3. 1 三种结构 使用这三种结构设计的程序容易理解、调试和修改。本章介绍选择结构和循环结构 的实现方法。 3.选择结构 1 计算机之所以有广泛的应用,在于它不仅能简单和按顺序地完成人们事先安排好的 一些指令,更重要的是具有逻辑判断能力,能针对不同情况执行不同指令序列,允许程序 “选择”适当的动作过程。选择结构根据不同的条件来选择不同的操作,需要使用if语句 实现。 3.1 语句块 1. 语句块不是一种语句,而是一组语句。如果实现选择结构或循环结构,当条件为真时 执行或者执行多次的系列操作都用语句块来实现。 50 计算思维与Python 应用编程 1.创建语句块 在语句前放置空格或Tab键缩进语句,即可创建语句块。同一个语句块其所有语句 缩进应相同。Python推荐的缩进方式是使用空格进行的,一个语句块缩进4个空格。 2.语句块的开始与结束 在Python中,使用冒号( )标识语句块的开始,块中的每一条语句都是缩进的(缩进 量相同)。在恢复成和原来的块一样缩进量时,表示当前块结束。 在Java、C、C++等高级语言中,使用特殊的字符({)表示一个语句块的开始,用另一 个字符(})表示语句块的结束。 语句块的开始与结束方式如图3.2所示。 图3.2 语句块的开始与结束 3.1.2 简单if语句 简单if语句实现的是“如果……那么……”的执行流程。 例3.1 输入一个数,输出其绝对值。 输入的数可能是正数,也可能是负数。如果是负数,那么绝对值为其相反数。 x=int(input("please input a number:")) if x<0: x=-x print(x) 执行上面的程序,假设输入负数-23,则输出其绝对值23。如果输入正数23,则输出 正数自身。 1.简单if语句格式 if 条件: 语句块 if关键字后面跟的条件是一个表达式。执行if语句时,首先对条件表达式求值,如果 结果为真,则执行语句块,否则什么也不做。在例3.1中,如果输入的值为负数,x<0的 值为True,那么执行语句块x=-x,对负数求相反数,得到其绝对值。如果输入的是正数, x<0的值为False,不执行语句块。简单if语句的流程如图3.3所示。 第3 章 流程控制 51 图3.3 简单if语句 流程图 2.条件表达式 if语句条件表达式的值通常为布尔类型,也称为布尔表达式。 条件可以是单条件,也可以是多条件。 常用的单条件包括如下。 . 数字比较,检查两个数字相等(==)、不等(!=)、大于(>)、 小于(<)、大于或等于(>=)和小于或等于(<=)。 . 字符串比较,检查两个字符串相等(==)和不等(!=)。 当存在多个条件时,需要根据条件之间的逻辑关系,用and或 or对各个条件进行逻辑运算。 例3.2 输入一个数,如果是偶数,输出提示。 x=int(input("请输入一个数:")) print("你输入的是",x) if x%2==0: print(x,"是偶数") 例3.3 小明今年12岁,再过10年,小明还是不是青少年? x=12 if x+10<13 or x+10>19: print("10 年后小明不是青少年") if x+10>=13 and x+10<=19: print("10 年后小明是青少年") 假设青少年定义为13~19岁。是青少年的条件可以描述为大于或等于13岁并且小于 或等于19岁;不是青少年的条件可以描述为小于13岁或者大于19岁(如图3.4所示)。 图3.4 多条件之并且及或者关系 3.非布尔类型返回值的条件表达式 如果条件表达式的类型是数值类型、字符串或其他的对象类型,Python会根据取值 情况认定True或False。 认定是False的包括布尔型False、整数0、浮点数0.0、null类型None、空字符串''、空 列表[]、空元组()、空字典{}等,也就是将数值0和各种空对象类型认定为False。 其他情况认定为True。 x=1 if x: print("x=1") 52 计算思维与Python 应用编程 上面的程序的运行结果是输出x=1。 3.1.3 if-else语句 if-else语句实现的是“如果……那么……否则……”的执行流程,在条件为真时执行 一个操作并在条件为假时执行另一个操作。if-else语句类似于简单的if语句,但其中的 else语句能够指定条件为假时要执行的操作。 例3.4 用if-else语句实现例3.3。 x=12 if x+10>=13 and x+10<=19: print("10 年后小明是青少年") else: print("10 年后小明不是青少年") 1.if-else语句格式 if 条件: 语句块1 else: 语句块2 if后面跟的条件是布尔表达式。执行if-else语句时,首先对条件求值,如果结果为 真,则执行语句块1,否则执行语句块2。if-else语句的流程图如图3.5所示。 图3.5 if-else语句流程图 2.if语句嵌套 if-else实现了两个分支的流程处理,如果处理多分支情况,则可以在if语句块中包含 if语句,即if语句实现嵌套。 例3.5 用if-else语句实现符号函数。 y= 1 (x>0) 0 (x=0) -1 (x<0) ì . í .. .. 第3 章 流程控制 53 符号函数取值包括三种情况,可以分解为x>0和x≤0两种情况,x≤0又可分解为 x<0和x=0两种情况(如图3.6所示)。 图3.6 嵌套流程 x=0.5 if x>0: y=1 else: if x<0: y=-1 else: y=0 print("y=",y) 嵌套的if语句也可以写在if部分。 3.1.4 if-elif-else语句 使用嵌套if语句可以实现多分支的选择,在分支较多时非常烦琐,Python提供了一 种将elseif合并的简写方法,格式如下。 if 条件1: 语句块1 elif 条件2: 语句块2 …e lif 条件n : 语句块n else: 语句块n +1 例3.6 将百分制成绩转换为五级制。 score=int(input("please input a score:")) if score>=90: grade="A" elif score>=80: 54 计算思维与Python 应用编程 grade="B" elif score>=70: grade="C" elif score>=60: grade="D" else: grade="E" print("grade=",grade) 程序运行时,首先测试score>=90是否为真。若为真,则该成绩为A,结束if语句, 否则测试scroe>=80……如果最终进入了else的语句块,那么表明score<60,成绩为 E,最后输出五级制成绩。程序实现了5个分支,将0~100划分成[90,100]、[80,90)、 [70,80)、[60,70)和[0,60)。 3.2 循环结构 在很多问题中,往往需要有规律地重复某些操作,这些操作在计算机程序中体现为某 些语句的重复执行,这就是循环。通过使用循环结构,只要写很少的语句,计算机就会反 复执行,完成大量同类运算。 3.2.1 while语句 Python中最简单的循环语句是while,实现“当……时则重复执行……”的流程。 例3.7 输出1~100的所有数。 count=1 while count <=100: print(count) count=count+1 执行while语句时,首先计算表达式count<=100,如果为True,则执行下面的语句 块,输出count的值并将count加1。语句块执行完成后,返回到while语句开始位置,重 新计算表达式,再次决定是否执行语句块,直到条件为False,退出循环。 1.while语句格式及执行流程 while 条件: 语句块 while语句的条件与if语句一样,可以是任意类型的表达式,通常是结果为布尔类型 的关系表达式或逻辑表达式。 执行while语句时,首先计算表达式的值,如果表达式的值为True,则执行循环体语 第3 章 流程控制 55 图3.7 while语句 执行流程 句块。然后重新计算表达式的值,再次判断值是否为True,如果 为True,再执行循环体语句块,如此循环往复;如果表达式的值为 False,则退出循环。 while语句执行流程如图3.7所示。 例3.8 计算1~100的所有数之和。 sum=0 i=1 while i<=100: sum=sum+i i=i+1 print(sum) 程序利用变量sum 保存求和结果,加数保存在变量i中。第一个数为1,在变量i小 于等于100时,while语句条件为真,执行循环体,将变量i值加到sum 中。为了再次执行 循环体时加下一个数,将变量i加1。循环体执行结束后,再次判断条件是否为真,如果为 真则再次执行循环体。当条件不满足,即i=101时,循环结束,输出sum 的值5050。 对于循环次数有限的while语句,为确保循环能够正常结束,不陷入死循环(也称为 无限循环,即条件一直为真),需要在执行若干次循环后,将条件表达式取值变为假,结束 循环。循环体中一定要包含能使循环条件变为假的语句,例如上面代码中的i=i+1。 例3.9 利用莱布尼茨级数求圆周率的值。 莱布尼茨级数为 π 4 =Σ∞ k=0 (-1)k 2k +1 级数的各项在k 为奇数时分子为-1,偶数时分子为1;也就是级数上一项分子为1, 下一项分子为-1。 t=1 sum=0.0 k=0 while k<=1000: sum=sum+t/(2*k+1) t=-t k=k+1 print("pi=",sum*4) 程序运行后输出pi=3.1425916543395442。 如果将循环次数修改为30000000,计算结果会更精确,输出pi=3.1415926869232984。 2.continue语句 continue语句在循环结构中执行时,将会立即结束本次循环,重新开始下一轮循环; 也就是说,跳过循环体中在continue语句之后的所有语句,继续下一轮循环。 56 计算思维与Python 应用编程 例3.10 由大到小输出10以下不能被3整除的自然数。 x=10 while x>=0: if x%3==0: x=x-1 continue print(x,end= " ") x=x-1 输出结果为10875421。 当x为3的倍数时,使用continue结束本次循环,如3、6、9等不输出。由于循环变量 修改在print语句之后,为正确进入下一次循环,在continue之前修改循环变量x的值。 使用print()函数输出时,默认情况下会输出一个换行符。print()输出的结束符号是 通过参数end="\n"设置的,本例中将结束符号修改为空格字符,在print()函数中加入 end="",end参数与输入内容间用逗号分隔。 print(x,end="")执行时输出x和一个空格。 3.break语句 break语句在循环结构中执行时,将会跳出循环结构,转而执行while语句后的语句, 即不管循环条件是否为假,遇到break语句将提前结束循环。break语句只结束当前 while语句的循环。 例3.11 由大到小输出10以下的自然数,遇到能被3整除的自然数时结束循环。 x=10 while x>=0: if x%3==0: break print(x,end= " ") x=x-1 输出结果为10。 continue语句和break语句的执行流程如图3.8所示。 图3.8 break语句与continue语句的流程 第3 章 流程控制 57 4.循环次数控制 while语句既可以实现次数固定的循环,也可以实现次数不固定的循环。无论是哪种情 况,程序中一定要有能够使循环条件变为假或退出循环的代码,避免运行时陷入死循环。 在实现次数固定的循环时,通常设置一个变量控制循环次数,先对循环变量赋初始值; 在条件中使用循环变量设置表达式,在未达到循环次数前表达式值为真;在循环体中修改循 环变量取值,最终经过若干次循环后条件表达式值为假而结束循环。如图3.9(a)所示。 在实现次数不固定的循环时,在循环体中使用if语句判断循环是否结束。在if语句 条件为真时,通常使用break语句结束循环,如图3.9(b)所示。 例3.12 编写程序,计算满足12+22+32+…+n2<1000的n 的最大值。 方法一:使用条件表达式控制循环流程。 i=0 sum=0 while sum<1000: i=i+1 sum=sum+i*i print(i-1) 方法二:使用if语句和break语句控制循环过程。 i=0 sum=0 while True: i=i+1 sum=sum+i*i if sum>1000: break print(i-1) 方法二中的条件表达式为True,while语句会一直执行循环体。在循环体执行过程 中,当sum>1000时,执行break语句退出循环。退出循环时,i变量为最大n 值的下一 次循环取值,最大n 值为i-1。 方法三:使用if语句和标志变量控制循环过程。 在循环存在多种条件时,为了让程序变得更为整洁,可定义一个变量作为循环条件, 这个变量称为标志。在标志为True时继续执行循环体,在任何条件不满足而将标志的 值设为False时退出循环。这样,在while 语句中就只需要检查标志的当前值是否为 True,所有检查是否满足条件的程序都放在其他地方。如图3.9(c)所示。 i=0 sum=0 flag=True while flag: i=i+1 58 计算思维与Python 应用编程 sum=sum+i*i if sum>1000: flag=False print(i-1) 图3.9 while语句的循环次数控制方法 上面三种方法的输出结果都是13。 5.交互式循环 while语句可以编写交互式循环,一般用于进行输入控制,由用户决定是继续输入 (执行循环)还是退出。 例3.13 输入一组整数,求输入整数的和。 sum=0 while True: t=input("please input a integer(input 'n' to exit):") if t!='n': sum+=int(t) else: break print("sum=",sum) 程序运行结果如图3.10所示。 图3.10 输入整数求和 第3 章 流程控制 59 3.2.2 while-else语句 while循环结束后,如果想确定是否执行了break语句,可以根据循环变量的取值进 行判断。 例3.14 判断正整数n是否是素数。 素数是只能被1和自身整除的数,如果n能够被2~n-1的任何一个数整除,则n不 是素数。 n=int(input("please input a integer(>2):")) i=2 while i2):")) i=2 while i=22: B.if(a>=22) C.if(a=>22) D.ifa>=22 3.以下关键字( )是用于给if语句添加其他条件语句的。 A.elseif B.elseif C.elif D.以上都不是 4.以下代码中( )是正确的for循环语句。 A.for(a=0;a<3;a++) B.forainrange(3) C.foraloop3: D.forainrange(1,3): 5.以下代码中( )是正确的while循环语句。 A.whileloopa<10 B.whilea<10: C.while(a<10) D.whileloopa<10: 6.以下可以只终结本次循环的保留字是( )。 A.if B.break C.exit D.continue 7.下列程序的运行结果是( )。 n=0 while n<=2: 第3 章 流程控制 63 print(n) A.2 B.3 C.死循环,无限个0 D.有语法错误 8.以下代码的输出结果为( )。 x,y,z=True,False,False if x or y and z: print("yes") else: print("no") A.yes B.no C.有语法错误D.运行错误 9.以下代码的输出结果为( )。 if None: print("Hello") A.False B.Hello C.没有任何输出D.语法错误 10.在if-elif-else的多个语句块中只会执行一个语句块,这样的说法( )。 A.正确B.错误 C.根据条件决定D.Python中没有elif语句 11.在Python中,for和while与else语句的关系是( )。 A.只有for才有else语句B.只有while才有else语句 C.for和while都可以有else语句D.for和while都没有else语句 12.以下代码的输出结果为( )。 i=sum=0 while i<=4: sum+=i i=i+1 print(sum) A.0 B.10 C.4 D.以上结果都不对 13.以下描述正确的是( )。 A.break语句用于终止当前循环 B.continue语句用于跳过当前剩余要执行的代码,执行下一次循环 C.break和continue语句通常与if、if-else和if-elif-else语句一起使用 D.以上说法都是正确的 14.以下代码的输出结果为( )。 x,y,z=True,False,False if not x or y: print(1) 64 计算思维与Python 应用编程 elif not x or not y and z: print(2) elif not x or y or not y and x: print(3) else: print(4) A.1 B.2 C.3 D.4 15.关于结构化程序设计所要求的基本结构,以下选项中描述错误的是( )。 A.重复(循环)结构B.选择(分支)结构C.goto跳转D.顺序结构 二、编程题 1.编写程序,用户输入4个数值(整数或浮点数)。先计算出三个数的平均值,然后 把平均值与第四个数比较。如果相等,则程序在屏幕上输出Equal。 Enter first number:4.5 Enter second number:3 Enter third number:3 Enter four number:3.5 Equal 2.体重指数BMI=体重(千克)/身高(米)的平方,即kg/m2。体重过轻:BMI<18; 体重正常:BMI=18~25;体重过重:BMI>25。编写程序,输入体重和身高,输出身体 状况信息和建议(如“您的体重过重,请加强锻炼”)。 3.编写使用函数range()的for循环语句,输出如下序列。 (1)0 1 (2)0 (3)3456 (4)1 (5)0 3 (6)5 9 13 17 21 4.编写程序,用户输入一个正整数n,在屏幕上输出前4个n的整数倍数。 5.编写程序,用户输入一个正整数n,在屏幕上输出0~n(不包括n)的平方。 6.编写程序,用户输入一个正整数n,在屏幕上输出n的所有正因子。例如输入49, 输出1、7和49。 7.编写程序,用户输入一个四位数的整数,使用标准的算术运算符处理该整数,在屏 幕上输出各位数字。例如输入1234,最后在屏幕上按顺序输出1、2、3、4。 8.编写一段while循环,计算以下值。 (1)前n 个数的和:1+2+3+…+n。 (2)前n 个奇数的和:1+3+5+…+(2n-1)。 (3)求用户输入的一系列数字的总和,直到输入值为999(注意,999不应该加入总和)。 (4)整数n 可以被2除(使用整数除法)的次数,直到结果为1(即log2n)。 (5)从5~100找出能被5或7整除的数。 (6)输出1000~1200的素数。 9.使用for语句实现第8题中的各小题。 10.有四个数字1、2、3、4,能组成多少个互不相同且无重复数字的三位数? 各是多 少?(百位、十位、个位的数字取值都可以是1、2、3、4,但是不能相等)。 11.输入两个均不超过9的正整数a和n,要求编写程序求a+ a+ a++…+ a…a (n个a)之和。提示: a=a×10+a,例如99=9×10+9 。 12.编写程序,计算序列1+1/3+1/5+…的前 N 项之和, N 从键盘输入。 13.编写程序,计算交错序列1-2/3+3/5-4/7+5/9-6/11+…的前 N 项之和, N 从键盘输入。 14.一个球从100米高度自由落下,每次落地后反跳回原高度的一半,再落下,再反 弹。求它在第10次落地时,共经过多少米? 第10次反弹多高? 15.输出所有的“水仙花数”。例如,153是水仙花数,因为153=13+53+33。 16.一个数如果恰好等于它的因子之和,则这个数称为“完数”。例如,6的因子为1、 2、3,而6=1+2+3,因此6是完数。编写程序,输出1000之内的所有完数。 17.输入三个整数x、y、z,把这三个数由小到大输出。 18.设有5分制测验,等级为5———A、4———B、3———C、2———D、1———E、0———F。编 写程序,输入测验成绩并打印出相应的等级。 第 3 章流程控制 65