第4章 程序的控制结构

来自CloudWiki
跳转至: 导航搜索

程序的三种控制结构

程序流程图

程序控制结构基础

程序通常由顺序结构、选择结构和循环结构3种基本结构组成。

1996年,计算机科学家Bohm和Jacopini证明了:任何简单或复杂的算法都可以由顺序结构、选择结构和循环结构这三种基本结构组合而成。

顺序结构

  • 任何编程语言中最常见的程序结构就是顺序结构。顺序结构就是程序从上到下逐行地执行,一直到程序的末尾,中间没有任何判断和跳转。这种结构如图2-7所示:
  • Java2-30.png

选择结构

  • Java中提供了两种常见的分支结构:if语句和switch语句,其中if语句使用布尔表达式或布尔值作为分支条件进行分支控制;而switch语句则用于对多个整型值进行匹配,从而实现分支控制。
  • Java2-31.png

循环结构

  • 循环结构是指在满足循环条件的情况下,反复执行某一段代码。具体内容在2.3节进行详细描述。
  • Java2-32.png

判断条件及组合

关系运算符

  • 下面是由关系运算符所组成的条件表达式:
>>> a ,b ,c = 1 ,2 , 3
 >>> print(a<b)
 True
 >>> print(b>c)
 False
  • Python中的关系运算符可以连续使用,这样不仅可以减少代码量,也比较符合人类的思维方式。
>>> print(a<b<c)                 #等价于1<2 and 2<3
 True
 >>> print(a<b>c)
 False
 >>> print(a<c>b)
 True
  • 在Python语法中,条件表达式中不允许使用赋值运算符“=”,避免了误将关系运算符“==”写作赋值运算符“=”带来的麻烦。在条件表达式中使用赋值运算符“=”将抛出异常,提示语法错误。
>>> if a=1:
	print('ok!')
	
SyntaxError: invalid syntax
>>> if a==1:
	print('ok!')	
ok!

逻辑运算符

  • 逻辑运算符and和or具有短路求值或惰性求值的特点,可能不会对所有表达式进行求值,而是只计算必须计算的表达式的值。
  • P4-1.png
  • 以“and”为例,对于表达式“表达式1 and 表达式2”而言,如果“表达式1”的值为“False”或其他等价值时,不论“表达式2”的值是什么,整个表达式的值都是“False”,丝毫不受“表达式2”的影响,因此“表达式2”不会被计算。
  • 在设计包含多个条件的条件表达式时,如果能够大概预测不同条件失败的概率,并将多个条件根据“and”和“or”运算符的短路求值特性来组织顺序,可以大幅度提高程序运行效率。
  • 代码:
>>> a ,b ,c = 1 ,2 , 3
>>> a < b and b < c
True
>>> a < b or b > c
True
>>> a > b and b < c
False
>>> a > b or b > c
False
>>> not a < b
False
>>> not b > c
True

程序的分支结构

单分支结构

s = eval(input("请输入一个整数:"))
if s%2 == 0:
    print("这是个偶数")
print("输入数字是:",s)

条件是一个或多个条件,多个条件间采用and或or 进行逻辑组合,and 表示多个条件"与"的关系,or表示多个条件"或"的关系。

s = eval(input("请输入一个整数:"))
if s%3 ==0 and s%5 == 0:
    print('这个数字既能被3整除,又能被5整除')
print("输入数字是:",s)


s = eval(input("请输入一个整数:"))
if s%3 ==0 or s%5 == 0:
    print('这个数字能被3整除,或能被5整除')
print("输入数字是:",s)


二分支结构

Python的二分支结构使用if-else保留字对条件进行判断,语法格式如下:

if 表达式:
    语句块1
else:
    语句块2

例题:

s = eval(input("请输入一个整数:"))
if s%3 ==0 and s%5 == 0:
    print('这个数字既能被3整除,又能被5整除')
else:
    print('这个数字不能同时被3和5整除')

Python还提供了一个三元运算符,并且在三元运算符构成的表达式中还可以嵌套三元运算符,可以实现与选择结构相似的效果。语法为

value1 if condition True else value2
s = eval(input("请输入一个整数:"))
result = "能被3整除" if s%3 == 0 else "不能被3整除"
print(result)

多分支结构:if-elif-else

if 表达式1:
    语句块1
elif 表达式2:
    语句块2
elif 表达式3:
    语句块3
else:
    语句块4


score = eval(input("请输入一个百分制成绩:"))
if score > 100 or score < 0:
    s = 'wrong score.must between 0 and 100.'
elif score >= 90:
    s = 'A'
elif score >= 80:
    s = 'B'
elif score >= 70:
    s = 'C'
elif score >= 60:
    s = 'D'
else:
    s = 'E'

print("您的成绩等级为:"+s)

程序的循环结构

遍历循环:for

遍历循环,可以理解为从遍历结构中逐一提取元素,放在循环变量当中。

对于字符串,可以逐一遍历字符串当中的每个字符。

for c in "Python":
    print(c)

使用range()函数,可以指定语句块的循环次数。

>>> for i in range(5):
    print(i)

遍历循环还有一种扩展模式,即增加else语句。

for s in range(5):
    print("程序执行中:"+str(s))
else:
    s = "循环正常结束"

print(s)

可以把循环中的else语句想象成一种奖励:当程序辛苦的执行全部循环的时候,没有中途退出或停止,则额外给予一段程序执行的奖励。


  • 问题解决:输出1~100之间能被7整除但不能同时被5整除的所有整数。
for i in range(1, 101):
    if i%7==0 and i%5!=0:
        print(i)

else一般用于当遍历未达预期时,需要显示的信息。


  • 问题解决:计算1+2+3+…+99+100的结果。
s = 0
for i in range(1, 101):            #不包括101
    s += i

print(s)

无限循环

  • while循环:
一般用于循环次数难以提前确定的情况,当然也可以用于循环次数确定的情况;

无限循环结构的语法形式分别为:

while 条件表达式:
    循环体

n = 0
while n<10:
    print(n)
    n = n+3

无限循环,也有一种使用保留字else的扩展模式。

while 条件表达式:
    循环体
[else:
    else子句代码块]

在这种扩展模式中,当while循环正常执行之后,程序会继续执行else语句中的内容。

n = 0
while n<10:
    print(n)
    n = n+3
else:
    print("循环正常结束")

循环控制:break和continue

循环结构有两个辅助循环控制的保留字:break和continue。

break用于跳出最内层for或while循环,跳出该循环后,从循环后的代码继续执行。

 while True:
      name = input("请输入姓名:(退出请输入quit)")
      if name == "quit":
           break;
      print(name)
print("程序退出.")
      
  • 如果有两层或多层循环,break退出最内层循环。
  • continue语句的作用是提前结束本次循环,忽略continue之后的所有语句,提前进入下一次循环。
  • 示例:本地车免检
 while True:
      name = input("请输入车牌号:")
      if name == "quit":
           break;
      if "鲁A" in name:#如果是本地车牌,略过本车,继续下一个
           continue;
      else:
           print(name,"号码的车主,请缴通行费")
      

程序的异常处理

观察下面这段小程序 <nowiki>>>> num = eval(input("请输入一个整数: ")) 请输入一个整数: 100

如果用户输入的不是数字呢?

>>> num = eval(input("请输入一个整数: "))
请输入一个整数: NO
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    num = eval(input("请输入一个整数: "))
  File "<string>", line 1, in <module>
NameError: name 'NO' is not defined
>>> 

由于使用了eval()函数,如果用户输入不是一个数字,则可能报错。这类由于输入与预期不匹配而造成的错误有很多种可能,不能逐一列出可能性进行判断。为了保证程序运行的稳定性,这类运行错误应该被程序捕获,并合理控制。

Python使用try-except语句实现异常处理,其基本语法格式如下“

try:
    <语句块1>
 except <异常类型>:
    <语句块2>
  • 为上面的小程序增加异常处理,程序如下。
try:
    num = eval(input("请输入一个整数: "))
    print(num**2)
except NameError:
    print("输入错误,请输入一个整数!")

这时如果程序在运行过程中,遇到因为用户输入而导致的错误,那么他就不会因此造成程序崩溃,而是及时被程序所捕获,并合理控制。

除了最基本的try-except语句,Python异常,还有一些略为高级的用法,这些方法在实际程序设计中也十分有用。

比方说,try-except语句可以支持多个excpet语句,语法格式如下。

try:
     <语句块1>
 except <异常类型1>:
     <语句块2>
 ...
 except <异常类型N>:
     <语句块N+1>
 except:
     <语句块N+2>

其中,第一个到第n个except语句后面都指定了异常类型,说明这些except所包含的语句块只处理这些类型的一种,其中最后一个except语句没有指定任何类型,表示他,对应的语句块,可以处理其他所有异常。

try:
    alp = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    idx = eval(input("请输入一个整数: "))
    print(alp[idx])
except NameError:
    print("输入错误,请输入一个整数!")  
except:
    print("其他错误")

除了try和except语句外,异常语句还可以与else、finally保留字配合使用。

try:
    alp = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    idx = eval(input("请输入一个整数: "))
    print(alp[idx])
except NameError:
    print("输入错误,请输入一个整数!")
else:
    print("没有发生异常")
finally:
    print("程序执行完毕,不知道是否发生了异常")

实例解析:猜数字游戏

编写一个猜数字游戏的程序,在1到1000之间随机产生一个数,然后请用户循环猜这个数字,对于每个答案只回答猜大了或猜小了,直到猜准确为止,输出用户的猜测次数。

当然运气好一次就能猜,对运气不好,要才999次,这就是猜测次数的边界了,来试一试,用户究竟几次能猜对呢。

提示:为了产生随机数,需要使用Python语言的随机数标准库random:

import random
target = random.randint(1,1000)

根据程序需求,需要考虑不断的让用户循环输入猜测值,并根据猜测值和目标值之间的比较决定程序逻辑。

练习2

输入一个年份,输出是否是闰年(什么是闰年,大家可以自行百度)

练习3

统计不同字符个数,用户从键盘输入一行字符,编写一个程序,统计并输出其中英文字符、数字、空格和其他字符的个数。