第3章控制语句.docx
《第3章控制语句.docx》由会员分享,可在线阅读,更多相关《第3章控制语句.docx(24页珍藏版)》请在冰豆网上搜索。
第3章控制语句
第3章 算法设计的基本方法
教学目的:
通过本章的学习,使学生掌握算法的基本知识,了解关系运算与逻辑运算
,学会使用选择结构和循环型结构进行程序设计。
知识点:
1.算法的概念、特点及描述
2.判断(关系运算与逻辑运算)
3.选择型程序设计
4.循环型程序设计
重点:
1.算法的描述
2.关系运算符和关系表达式
3.逻辑运算符和逻辑表达式
4.条件运算符及条件表达式
5.IF语句的格式使用
难点:
复杂条件的表示;IF语句的正确使用。
3.1算法
●程序是计算机的灵魂
●算法是程序的灵魂
一个程序应包括两个方面的内容:
著名计算机科学家沃思提出一个公式:
数据结构+算法=程序
●对数据的描述:
数据结构(datastructure)
●对操作的描述:
算法(algorithm)
完整的程序设计应该是:
数据结构+算法+程序设计方法+语言工具
3.1.1算法的组成要素和基本性质
(1)算法的概念
解决问题的一种方法或过程的描述,(是对特定问题求解步骤的一种描述。
)一个问题可能有多种算法对应。
或算法是由一系列操作组成的。
(2)算法的组成要素
✓操作:
与问题和所用的工具有关。
✓控制结构:
每一个算法都要由一系列的操作组成。
同一操作序列,按不同的顺序执行,就会得出不同的结果。
控制结构即如何控制组成算法的各操作的执行顺序。
控制结构:
◆顺序控制结构:
语句是按照书写顺序执行的,也就是语句的执
行顺序与书写顺序一致。
只有这种结构不可能处理复杂问题。
◆选择控制结构:
当程序执行到某一条语句时,要进行某种判断,从两支或多分支选择其中一条执行。
◆循环控制结构:
将一条或多条语句重复执行若干次。
有了选择和循环控制结构,就可以设计复杂大型的程序了。
(3)算法的性质
✓①效性:
算法所规定的操作都应能有效执行的。
✓②定性:
描述的操作应当具有明确的含义;序列中只有一个初始动作,每一动作仅有一个后继动作;序列终止表示问题得到解答或问题没有解答,不能没有任何结论。
✓③穷性:
所规定的操作序列必须在允许的时间内结束。
✓④输入
✓⑤输出
3.1.2算法的描述工具
✓1)流程图
方法:
用一些图框表示各种类型的操作,用线表示这些操作的执行顺序。
举例:
用流程图描述从3个数据中取最大数的算法。
✓2)N-S图
●方法:
每一种基本结构都是一个矩形框,整个算法可以像堆积木一样堆成。
举例:
用N-S图描述从3个数据中取最大数的算法。
✓ 3)伪代码
●举例:
用伪代码描述从3个数据中取最大数的算法。
算法1(使用选择结构)
输入a,b,c;
if(a>=b)
max=a;
else
max=b
if(max>=c)
输出max;
else
输出c;
算法2(使用循环结构)
初始化:
max=-32768,i=1;
当(i<=3)
(
输入n;
i++;
if(n>=max)
max=n;
)
输出max;
3.1.3结构化程序设计方法
由三种基本结构顺序组成的算法结构,可以解决任何复杂的问题。
由基本结构所构成的算法属于“结构化”的算法,它不存在无规律的转向,只在本基本结构内才允许存在分支和向前或向后的跳转。
一个结构化程序就是用高级语言表示的结构化算法。
用三种基本结构组成的程序必然是结构化的程序,这种程序便于编写、便于阅读、便于修改和维护。
结构化程序设计强调程序设计风格和程序结构的规范化,提倡清晰的结构。
构化程序设计方法的基本思路是:
把一个复杂问题的求解过程分阶段进行,每个阶段处理的问题都控制在人们容易理解和处理的范围内。
模块设计的方法:
☆模块化设计的思想实际上是一种“分而治之”的思想,把一个大任务分为若干个子任务,每一个子任务就相对简单了。
☆拿到一个程序模块以后,根据程序模块的功能将它划分为若干个子模块,如果这些子模块的规模还嫌大,还再可以划分为更小的模块。
这个过程采用自顶向下方法来实现。
☆模块一般不超过50行。
☆分子模块时应注意模块的独立性,即:
使一个模块完成一项功能,耦合性愈少愈好。
3.2判断
3.2.1命题的“真”、“假”与C语言中的逻辑值
✓逻辑(布尔)值:
“真”或“假”
✓早期的C语言不提供专门的逻辑(布尔)类型,规定用非0值表示“真”,用0值表示“假”。
这样,不管任何表达式,只要其值为非0(包括负数),就说明其为“真”;只要其值为0,就说明其为“假”。
✓在C99中,增加了_Bool类型,并增加了头文件,在其中定义了宏bool、true和false,用true存储1,用false存储0。
关系表达式和逻辑表达式是C语言中描述命题的两种基本形式。
3.2.2关系运算与关系表达式
✓关系运算符(左结合)
>>=<<===!
=
较高 较低
✓关系表达式
◆用关系运算符将运算对象连接成的式子
例如:
12<'C'+1(字符型数据比较ASCII值)
a==b>=c等价于a==(b>=c)
与(a==b)>=c不等价
✓关系运算符优先于赋值,低于算术
√说明:
◆ 关系运算的结果应该是逻辑值。
C语言用数值用1表示逻辑真,0表示逻辑假
例如:
7>5的值是1,5>7的值是0
'a'>'b'的值是0,'a'<'b'的值是1
即关系表达式的值:
0或1
◆实型数可进行大于或小于比较,但通常不进行==或!
=的关系运算。
voidMsort(intSR[],ints,intt)
3.2.3逻辑运算与逻辑表达式
✓逻辑运算符
&&||!
✓逻辑运算符的运算规则
运算对象
逻辑运算结果
a
b
a&&b
a||b
!
a
非0
非0
1
1
0
非0
0
0
1
0
0
非0
0
1
1
0
0
0
0
1
◆逻辑表达式
●用逻辑运算符将运算对象连接成的式子。
例如:
0&&'b'
a&&b||c&&d
a||b-5||c/4
!
x+y>=z
◆逻辑运算符的优先级和结合性:
●!
是单目运算符,右结合,高于算术
●&&和||是双目运算符,左结合,高于赋值运算符,低于关系运算符。
◆逻辑运算规则
从左到逻辑进行逻辑计算
●运算对象为非0表示逻辑真
●运算对象为0表示逻辑假
逻辑运算的结果为0或1
例如设:
a=15,b=0,c=-2
a&&b&&c结果为0
a||b||c结果为1
(a+c)||b&&c结果为1
◆运算按照从左至右的顺序进行,一旦能够确定逻辑表达式的值,就立即结束运算
√关系与逻辑运算符的应用
◆ 表示数学公式a>b>c:
a>b&&b>c
◆判断a,b,c三条线段能否组成一个三角形:
a+b>c&&a+c>b&&b+c>a
◆a,b不同时为负
3.3选择型程序设计
选择型程序描述了这样的求解规则:
在不同的条件下所应进行的相应操作。
3.3.1if…else结构
1)双分支结构
●语句一般格式
if(表达式)语句1else语句2
●功能:
计算表达式的值,如果它的值是一个非0值(逻辑真),就执行内嵌语句1,之后跳过内嵌语句2,执行后续语句;否则跳过内嵌语句1,执行内嵌语句2,之后执行后续语句。
●算法描述
例 求一个数的绝对值。
2)单分支结构
●语句一般格式
if(表达式)语句
●功能:
计算表达式的值,如果是一个非0值(即逻辑真),就执行内嵌语句,否则(即逻辑假)跳过内嵌语句,顺序执行后续语句。
●算法描述
●例如:
◆⑴if(x>0)m++;
◆⑵if(a>b)
{c=a;a=b;b=c;}
◆求3个数中最大数
3)if语句的嵌套
如果if的内嵌语句中又使用了一个if语句,则构成if语句的嵌套。
比较两个整数的关系。
#include
main()
{intx,y;
printf("EnterintegerXandY:
");
scanf("%d%d",&x,&y);
if(x!
=y)
if(x>y)printf("X>Y\n");
elseprintf("Xelseprintf("X=Y\n");
}
应该正确判断:
•if的内嵌语句
•if和else的配对
提倡缩格书写
有利于阅读程序
if语句嵌套的形式
•简单if语句的嵌套形式
if(表达式)
if语句
•双重(或多重)分支if语句的嵌套形式
if(表达式)
if语句
else
if语句
规则:
在嵌套的if~else语句中,else总是与上面的离它最近的尚未配对的if配对。
3.3.2if…elseif结构
●语句一般格式
if(表达式1)语句1
elseif(表达式2)语句2
……
elseif(表达式m)语句m
else语句n
●功能
◇依次计算并判断表达式i,为非0时执行后面的语句,都为0时,执行语句n
◇无论执行完那个语句分支,都转到后续语句
●流程图
● 例3.6根据百分制分数决定成绩的等级:
·80分以上为A级;
·70分及以上,80分以下,B级;
·60分及以上,70分以下,C级;
·60分以下,D级。
#include
intmain(void)
{
floatscore;
printf(“Inputascre:
”);
scanf(“%f”,&score);
if(score>=80)
printf(″%fisA\n″,score);
elseif(score>=70)
printf(″%fisB\n″,score);
elseif(score>=60)
printf(″%fisC\n″,score);
else
printf(″%fisD\n″,score);
return0;
}
3.3.3switch结构
●语句一般格式
switch(表达式)
{case常量表达式1:
语句序列1
case常量表达式2:
语句序列2
……
case常量表达式n:
语句序列n
default:
语句序列n+1
}
●功能
◆计算表达式的值,与常量表达式的值比较,等于第i个值时,顺序执行语句序列i、i+1、…、n+1。
◆若与所有常量表达式值都不相等,执行语句序列n+1。
●流程图
注意:
◆一个switch结构的执行部分是一个由一些case子结构与一个可缺省的default子结构组成的复合语句,它们位于一对花括号之中。
◆switch的判断表达式只能对整数求值,可以使用字符或整数,但不能使用浮点表达式。
case表达式应当是整型常数表达式,不能含有变量与函数的常数表达式
◆switch语句的书写格式:
语句体本身必须用花括号括起;case和default后面如果有多条语句,则可以不必使用花括号;case和常量表达式之间必须有空格;default可以写在语句体的任何位置,也可以省略不写;
◆break语句可以改变case的语句标号作用,终止后续case语句序列的执行。
switch语句和break语句结合,可以实现程序的选择控制(break语句还可以在循环语句中使用);
◆允许switch嵌套使用,但同一个switch语句中,任意两个case的常量表达式值不能相同。
◆一个switch结构中不可以出现两个具有相同值的常量表达式。
◆switch的匹配测试,只能测试是否相等,不能测试关系或逻辑。
switch结构允许嵌套。
3.3.4条件表达式
● 语句一般格式
表达式1?
表达式2:
表达式3
● 功能
若表达式的值为真(非0),则以表达式2的值作为该条件表达式的值;否则取表达式3的值作为该条件表达式的值。
3.4循环型程序设计
3.4.1迭代与穷举算法
(1)迭代是一个不断用新值取代变量的旧值,或由旧值递推出变量的新值的过程。
例:
①人口增长问题。
按年0.2%的增长速度,现有13亿人,10年后将有多少人?
分析:
设现人口数为m,则第1年后人口变为:
m=m*(1+0.2%)
即将m的值用m*(1+2%)替代。
②兔子繁殖问题。
Fibonacci曾提出一个有趣的问题:
设有一对新生兔子,从第三个月开始它们每个月都生一对兔子。
按此规律,并假设没有兔子死亡,一年后共有多少对兔子。
人们发现每月的兔子数组成如下数列:
1,1,2,3,5,8,13,21,34,…并把它称为Fibonacci数列。
分析:
每个月的兔子数由两部分组成:
上一月的老兔子数,这一月刚生下的新兔子数。
上一月的老兔子数即其前一个数。
这一月刚生下的新兔子数恰好为上上月的兔子数。
算法可以描述为
fib1=fib2=1
(1)
fibn=fibn-1+fibn-2(n>=3)
(2)
式
(1)为赋初值,式
(2)为迭代公式。
用C语言来描述式
(2)为:
fib=fib1+fib2;
fib1=fib2;/*为下一次迭代作准备*/
fib2=fib;
③一元方程的迭代解法。
一元方程f(x)=0,5次以上的方程找不出通用的根的解析表达式。
在这种情况下,人们不得不求助于一些近似解法。
方法:
二分迭代法
牛顿迭代法
(2)穷举
✓迭代是一个不断用新值取代变量的旧值,或由旧值递推出变量的新值的过程。
✓ 循环控制有两种办法:
计数法与标志法。
①输入10个数,将最大的一个数打印出来。
S1:
输入1个数,暂时作为擂主——最大数。
S2:
输入9个数——穷举这9个数,每输入一个,打一次擂台——把最大数与刚输入的数据进行比较,把大者作为新擂主——最大数。
S3:
输出最大数。
②例3.16百钱买百鸡问题。
cocks+hens+chicks=100
(1)
5*cocks+3*hens+chicks/3=100
(2)
cocks:
0~19中的整数(因为每只鸡翁5钱,因此它不可能超过19只)
hens:
0~33中的整数
chicks:
0~100中的整数
3.4.2while循环结构
(1)格式
while(表达式)
循环体语句
(2)执行流程
循环体在执行while语句时,先对判断表达式进行计算,若其值为真(非0),则执行循环体语句;否则跳过循环体,而执行该结构后面的语句。
在进入循环体后,每执行完一次循环体语句后,再对判断表达式进行一次计算和判断。
当发现判断表达式的值为0时,便立即退出循环。
(3)例
计算人口增长的C程序。
例3.18Fibonacci算法C语言的程序实现。
例3.20输入多个数,输出其中最大者的C程序。
3.4.3do…while结构
(1)格式
do
循环体
while(表达式);
当流程到达do后,立即执行循环体一次,然后才对判断表达式进行计算、测试。
若表达式的值为真(非0),则重复执行一次循环体;否则退出。
与while结构相比,do…while结构至少要执行一次循环体。
这样的结构应用在需要事先执行一次循环体的程序非常容易理解。
(3)例
3.4.4for结构
(1)格式
for(表达式1;表达式2;表达式3)
循环体
for(初始化表达式;判断表达式;修正表达式)
循环体
(2)执行流程
1)先执行表达式1(初始化表达式)。
注意在整个循环中它只执行一次。
2)重复下面的过程:
计算表达式2(判断表达式),若为真(非0),就执行一次循环体语句,然后再执行表达式3(修正表达式);再计算表达式2(判断表达式),判断是否为“真”,……直至表达式2(判断表达式)的值为假(0),就不再执行循环体了。
3.4.5循环嵌套
一个循环体内又包含另一个完整的循环结构称为循环的嵌套。
内嵌的循环中还可以嵌套循环,这就是多层循环。
三种循环(while循环、do-while循环和for循环)可以互相嵌套。
嵌套形式:
3.4.6 循环结构的中途退出与重复周期的中途结束
(1)break语句
break语句可以用来从循环体内跳出循环体,即提前结束循环,接着执行循环下面的语句
一般形式:
break;
注意:
break语句不能用于循环语句和switch语句之外的任何其他语句中。
(2)continue语句
提前结束一个循环周期——continue语句
3.4.7几种循环的比较
(1)四种循环都可以用来处理同一问题。
(2)在while和do-while循环中,应在循环体中包含使循环趋于结束的语句。
for可以在表达式3中包含使循环趋于结束的操作。
(3)循环变量初始化的操作应在while和do-while语句之前完成。
而for可以在表达式1中实现循环变量的初始化
(4)while、do-while和for循环,可以用break语句跳出循环,用continue语句结束本次循环。
而对用goto构成的循环,不能用break语句和continue语句进行控制。