第5讲结构化程序设计之流程控制语句.docx

上传人:b****8 文档编号:9339307 上传时间:2023-02-04 格式:DOCX 页数:64 大小:604.76KB
下载 相关 举报
第5讲结构化程序设计之流程控制语句.docx_第1页
第1页 / 共64页
第5讲结构化程序设计之流程控制语句.docx_第2页
第2页 / 共64页
第5讲结构化程序设计之流程控制语句.docx_第3页
第3页 / 共64页
第5讲结构化程序设计之流程控制语句.docx_第4页
第4页 / 共64页
第5讲结构化程序设计之流程控制语句.docx_第5页
第5页 / 共64页
点击查看更多>>
下载资源
资源描述

第5讲结构化程序设计之流程控制语句.docx

《第5讲结构化程序设计之流程控制语句.docx》由会员分享,可在线阅读,更多相关《第5讲结构化程序设计之流程控制语句.docx(64页珍藏版)》请在冰豆网上搜索。

第5讲结构化程序设计之流程控制语句.docx

第5讲结构化程序设计之流程控制语句

第5讲结构化程序设计之流程控制语句

教学过程设计

一新课引入

默认情况下程序是顺序执行的。

当程序员在编写程序时并不知道在一次具体执行中执行者会做些什么时,他可以建立一个执行者用以作出判定的标准。

例如:

“朋友来了,端出好酒;豺狼来了,拿出猎枪。

”。

有时程序的某部分可能需要执行多次。

例如:

在中草药炮制过程中,对某种药材要经过“九蒸九晒”才符合要求,这种重复必须指明重复的次数。

有时重复执行程序的某部分不一定有明确的次数,但可以以是否达到某个目标作为重复终止的判断依据。

例如:

在把假分数化成真分数时,可以从分子中不断地减去分母,直到分子小于分母为止。

操作之间的关系——操作流程包括:

顺序、选择、循环、转向(语言表达所需要的)。

其中顺序、选择、循环是三种基本结构,已经证明,由这三种基本结构组成的程序结构,可以解决任何复杂的问题。

由基本结构所构成的程序是结构化的程序,它不存在无规律的转向,只在本基本结构内才允许存在分支和向前或向后的跳转。

软件工程提倡程序员书写结构化的程序。

C语言提供的流程控制语句有——描述“选择”的语句有:

if语句、switch语句;描述“循环”的语句有:

while语句、do-while语句、for语句;描述“转向”的语句有:

goto语句、break语句、continue语句、return语句。

为了达到直观形象、易于理解的效果,我们在进行结构化编程的同时可以辅助以一种图形工具——结构化的流程图。

本讲将主要介绍关于四种操作流程:

顺序、选择、循环、转向的C语言描述、图形描述方法,以及由三种基本结构所构成的结构化的程序。

二讲授新课

1顺序

默认情况下程序是顺序执行的,所以C语言没有必要提供相关的描述语句来表示。

2选择

当程序员在编写程序时并不知道在一次具体执行中执行者会做些什么时,他可以建立一个执行者用以作出判定的标准。

例如:

“朋友来了,端出好酒;豺狼来了,拿出猎枪。

”。

C语言提供的描述“选择”的语句有:

if语句、switch语句。

if语句

1.if语句的两种形式

C语言提供了两种形式的if语句:

单分支选择if语句

if(“条件”表达式)

语句

说明:

“条件”表达式的类型不限于逻辑表达式,可以是任意的数值类型(包括整型、实型、字符型、指针型数据)。

在if和else后面可以只有一个操作语句,也可以有多个操作语句,此时需用花括号“{}”将几个语句括起来成为一个复合语句。

单分支选择if语句的流程图表示如下图所示。

单分支选择if语句的执行过程是:

求“条件”表达式的值。

如果“条件”表达式的值为真,则执行“语句”,否则不执行“语句”。

单分支选择if语句的功能是:

判定所指定的条件是否满足,根据判定的结果(真或假)决定是否执行给定的一组操作。

双分支选择if语句

if(“条件”表达式)

语句1

else

语句2

说明同上。

双分支选择if语句的流程图表示如下图所示。

双分支选择if语句的执行过程是:

求“条件”表达式的值。

如果“条件”表达式的值为真,则执行“语句1”,否则执行“语句2”。

双分支选择if语句的功能是:

判定所指定的条件是否满足,根据判定的结果(真或假)决定执行给定的两组操作其一。

2.if语句的嵌套

嵌套的if语句能实现多分支选择。

在if语句中又包含一个或多个if语句称为if语句的嵌套。

例如:

if(“条件”表达式)

  if(“条件”表达式)

语句1

else

语句2

else

if(“条件”表达式)

语句3

else

语句4

应当注意if与else默认的配对关系——else总是与其前面最近的if配对。

因此最好使内嵌if语句也包含else部分,这样if与else的数目相同,从内层到外层一一对应,不致出错。

如果if与else的数目不同,要改变这种默认的配对关系,可以加花括弧来确定配对关系。

例如:

if(“条件”表达式)

{

if(“条件”表达式)

语句1

}

else

语句2

这时{}限定了内嵌if语句的范围,因此else与第一个if配对。

常用的一种嵌套形式是:

if(“条件”表达式1)

语句1

elseif(“条件”表达式2)

语句2

elseif(“条件”表达式n)

语句n

else

语句n+1

说明同上。

其流程图表示如下图所示。

其执行过程是:

求“条件”表达式1的值,如果“条件”表达式1的值为真,则执行“语句1”,否则求“条件”表达式2的值,如果“条件”表达式2的值为真,则执行“语句2”,否则……,依此类推。

当出现某个“条件”表达式的值为真时,则执行其对应的语句。

如果所有的“条件”表达式的值均为假,则执行“语句n+1”。

其功能是:

多次判断。

每判断一步,都分别分离出一些范围(这些范围已能用于作出相应的结论),逐步缩小判定的范围,直到不必再缩小判定的范围就可以作出相应的结论。

switch语句

我们可以用嵌套的if语句来实现多分支选择,但如果分支越多,则多嵌套的if语句的层数就越多,程序冗长而且可读性降低。

某些时候,在使用嵌套的if语句时,所有的分支看起来都非常相似,因为它们都在对一个完全相同的“条件”表达式(“条件”表达式的类型只能为整型、字符型或枚举型)进行求值,惟一的区别是每个分支都将“条件”表达式的值与一个不同的值(也相应地只能为整型、字符型或枚举型)进行比较。

例如:

if(day==0)

dayName="Sunday";

elseif(day==1)

dayName="Monday";

elseif(day==2)

dayName="Tuesday";

elseif(day==3)

...

else

dayName="Unknown";

在这些情况下,通常需要将嵌套的if语句改写为一个使用break语句的switch语句,使程序更简洁、更易懂。

switch语句的一般形式如下:

switch(“条件”表达式)

{

case常量表达式1:

语句1

case常量表达式2:

语句2

case常量表达式n:

语句n

default:

语句n+1

其流程图表示如下图所示。

说明:

switch后面括号中的“条件”表达式的类型只能为整型、字符型或枚举型。

每一个case后面都需要一个常量表达式(例如:

1、'a'、3+4),且该常量表达式的值的类型要与switch后面括号中的“条件”表达式的值的类型相匹配。

每一个case后面的常量表达式的值必须互不相同,否则就会出现逻辑上互相矛盾的现象——对switch后面括号中的“条件”表达式的同一个值,有两种或多种执行方案。

一个switch语句中可以没有default标号或只能有一个default标号,default标号表示不是任何case标号所提供的其他情况。

default标号和各个case标号之间无先后顺序。

多个case标号可以共用一组执行语句。

例如:

case'A':

case'B':

case'C':

printf(">60\n");break;

grade的值为A、B或C时都执行同一组语句。

switch后面括号中的“条件”表达式实际上并非进行真正的条件判断,而只是一种跳转指示(与if语句不同),表示下面应该跳转到什么位置继续执行。

而各个“case常量表达式”和default实际上只是一个语句标号,并不是在该处进行条件判断。

执行时根据switch后面括号中的“条件”表达式的值找到匹配的入口标号,就跳转到此标号后面的语句处,并从此语句开始执行下去,而不再通过判断来决定是否继续执行——即执行完一个标号后面的语句后,流程控制转移到下一个标号后面的语句继续执行,直到整个switch语句结束(即遇到“}”)。

在标号后面虽然包含一个以上执行语句,但可以不必用花括号括起来,会自动顺序执行本标号后面所有的执行语句。

当然加上花括号也可以。

如果要在执行一个标号后面的语句组后使流程跳出switch语句,必须在其语句组最后加上break语句,最后一个标号可以不加break语句。

使用break语句的switch语句的一般形式如下:

switch(“条件”表达式)

{

case常量表达式1:

语句1

break;

case常量表达式2:

语句2

break;

case常量表达式n:

语句n

break;

default:

语句n+1

(break;)

其流程图表示如下图所示。

switch语句的执行过程:

首先计算switch后面括号中“条件”表达式的值(switch后面括号中的“条件”表达式只求值一次。

),然后在作为具体的复合语句中的语句序列中从前开始查找带case标号的带标号语句。

如果某个带case标号的带标号语句中case后常量表达式的值与所求得的“条件”表达式的值相同,那么就从该带标号语句开始往后执行,直到遇到break等语句退出该switch语句或执行到该复合语句末尾(执行到右花括号“}”处。

)。

如果没有一个带标号语句中case后常量表达式的值与所求得的“条件”表达式的值相同,那么就接着查找其后有无带default标号的带标号语句。

若有,则从default标号所标记的语句往后执行,直到执行到该复合语句末尾或遇到break等语句退出本switch语句;否则,不执行该复合语句中任何语句,直接退出switch语句。

选择结构的嵌套

程序举例

【例】由用户输入某一年份,判断该年份是否为闰年,并将判断结果输出到屏幕。

分析:

判断某一年份为闰年的方法为:

能被4整除,但不能被100整除;能被400整除。

满足以上两个条件中的任何一个条件都是闰年,否则都是非闰年。

至于如何得到这个判定定理,似乎不应该问程序员,更应该去问天文学家!

绘制与闰年的判定定理功能等价的判定表:

分析以上判定定理中的条件,我们可以从其中提取出3个原子断言:

能被4整除;能被100整除;能被400整除。

理论上对于这3个原子断言的真假有2*2*2=8个组合方式,如下表所示,下表中的书写规律为表达式year%400==0的值变化得最快,year%100==0次之,year%4==0的值变化得最慢:

year%4==0

year%100==0

year%400==0

但事实上,上表中有些情况根本不可能存在,具体情况及其原因如下表:

year%4==0

year%100==0

year%400==0

条件不可能同时成立

条件不可能同时成立

条件不可能同时成立

条件不可能同时成立

整理成下表:

year%4==0

year%100==0

year%400==0

再结合前面提到的闰年的判定定理,得到与闰年的判定定理功能等价的判定表,如下表所示:

year%4==0

year%100==0

year%400==0

闰年

有了这个判定表,我们解题的思路就清晰了。

下面的程序可供参考。

参考程序1:

一次判断。

main()

{

intyear;

scanf("%d",&year);

if(((year%4==0)&&(year%100!

=0))||(year%400==0))

printf("%disaleapyear.\n",year);

else

printf("%disnotaleapyear.\n",year);

}

参考程序2:

多次判断。

每判断一步,都分别分离出一些范围(这些范围已能用于判定是闰年或非闰年),逐步缩小判定的范围,直到不必再缩小判定的范围就可以作出相应的结论。

main()

{

intyear;

scanf("%d",&year);

if(year%4==0)

{

if(year%100==0)

{

if(year%400==0)

printf("%disaleapyear.\n",year);

else

printf("%disnotaleapyear.\n",year);

}

else

printf("%disaleapyear.\n",year);

}

else

printf("%disnotaleapyear.\n",year);

}

main()

{

intyear;

scanf("%d",&year);

if(year%4!

=0)

printf("%disnotaleapyear.\n",year);

elseif(year%100!

=0)

printf("%disaleapyear.\n",year);

elseif(year%400!

=0)

printf("%disnotaleapyear.\n",year);

else

printf("%disaleapyear.\n",year);

}

3循环

有时程序的某部分可能需要执行多次。

例如:

在中草药炮制过程中,对某种药材要经过“九蒸九晒”才符合要求,这种重复必须指明重复的次数;有时重复执行程序的某部分不一定有明确的次数,但可以以是否达到某个目标作为重复终止的判断依据。

例如:

在把假分数化成真分数时,可以从分子中不断地减去分母,直到分子小于分母为止。

常见的循环有两种:

循环次数可以确定;循环次数不能确定而只能给出循环结束条件。

C语言提供的描述“循环”的语句有:

while语句、do-while语句、for语句。

while语句

while(“条件”表达式)

循环体语句

说明:

循环体如果包含一个以上的语句,应该用花括号括起来,以复合语句形式出现。

如果不加花括号,则while语句的范围只到while后面第一个分号处。

对于循环次数可以确定的循环,循环控制变量初始化的操作应在while语句之前完成。

对于循环次数可以确定的循环,应在while语句的循环体中包含使循环趋于结束的语句。

可以用break语句跳出本层while循环,用continue语句结束本层、本次while循环。

while语句的流程图表示如下图所示。

while语句的执行过程是:

求“条件”表达式的值(即判断给定的条件是否成立),如果“条件”表达式的值为真(即给定的条件成立),则执行“循环体语句”。

再求“条件”表达式的值,如果“条件”表达式的值仍为真,则再执行“循环体语句”……,如此反复执行循环体语句,直到某一次“条件”表达式的值为假(即给定的条件不成立),此时退出while语句。

while语句的功能是:

既可以实现循环次数可以确定的循环,也可以实现循环次数不能确定的循环。

do-while语句

do

循环体语句

while(“条件”表达式);

说明同上。

do-while语句的流程图表示如下图所示。

do-while语句的执行过程是:

先执行一次“循环体语句”,然后求“条件”表达式的值(即判断给定的条件是否成立),如果“条件”表达式的值为真(即给定的条件成立),则返回重新执行“循环体语句”,然后再求“条件”表达式的值,如果“条件”表达式的值仍为真,则再返回重新执行“循环体语句”……,如此反复执行循环体语句,直到“条件”表达式的值为假(即给定的条件不成立),此时退出do-while语句。

do-while语句的功能是:

既可以实现循环次数可以确定的循环,也可以实现循环次数不能确定的循环。

for语句

for(表达式1;表达式2;表达式3)

循环体语句

for语句表达循环次数可以确定的循环时的一般形式如下:

for(循环控制变量赋初值;循环条件;循环变量增值)

循环体语句

说明:

“表达式1”可以省略,注意:

省略“表达式1”时,其后的分号不能省略。

执行时,跳过求解“表达式1”这一步,其他不变。

此时对于循环次数已经确定的for语句,应在for语句之前给循环控制变量赋初值。

“表达式2”可以省略,注意:

省略“表达式2”时,其后的分号不能省略。

执行时,认为“表达式2”的值始终为真,不在此处判断循环条件,其他不变。

此时应在循环体中判断循环条件,否则循环将无终止地进行下去。

“表达式3”可以省略。

执行时,跳过求解“表达式3”这一步,其他不变。

此时对于循环次数可以确定的循环,应在for语句的循环体中设置使循环趋向于结束的语句。

可以省略“表达式1”和“表达式3”,只有“表达式2”,即只给出循环条件,在这种情况下,for语句完全等价于while语句。

3个表达式都可以省略,即:

for(;;)

语句

相当于

while

(1)

语句。

“表达式1”可以是设置循环控制变量初值的赋值表达式,也可以是与循环控制变量无关的其他表达式。

可以在“表达式3”中包含使循环趋于结束的操作,也可以是与循环控制无关的需要循环执行的任意表达式,甚至可以将循环体中的操作全部放到表达式3中。

“表达式1”和“表达式3”可以是一个简单的表达式,也可以是逗号表达式。

“表达式2”一般是关系表达式或逻辑表达式,但也可以是数值表达式或字符表达式,只要其值为非零,就执行循环体。

可以用break语句跳出本层while循环,用continue语句结束本层、本次while循环。

for语句的流程图表示如下图所示。

for语句的执行过程是:

1.求解“表达式1”。

2.求解“表达式2”,若其值为真,则执行循环体语句,然后转到第3步。

若其值为假,则转到第5步。

3.求解“表达式3”。

4.返回上面第2步继续执行。

5.循环结束。

for语句的功能是:

既可以实现循环次数可以确定的循环,也可以实现循环次数不能确定的循环。

循环结构的嵌套

一个循环体内又包含另一个完整的循环结构,称为循环的嵌套。

内嵌的循环中还可以嵌套循环,这就是多层循环。

三种循环(while循环、do-while循环和for循环)可以互相嵌套。

三种循环语句的比较

程序举例

【例1】求1+2+……+100,并输出结果。

分析:

我们可以通过多个操作步骤解决这个问题:

首先计算前两个加数的和;其次使用求得的和与第三个加数相加,计算出前三个加数的和;再其次使用求得的和与第四个加数相加,计算出前四个加数的和;如此继续下去,直到计算出前100个加数的和。

第1次:

计算1+2;

第2次:

计算(1+2)+3;

第3次:

计算(1+2+3)+4;

……

第99次:

计算(1+... +99)+100。

从上面的分析可以看出:

这个问题可以通过99次加法运算完成,并且每次作加运算的操作对象——加数与被加数的变化都是各有规律的:

①容易看出加数从2变化到100,第一个加数是2,加数每次增加1即后一个加数比前一个加数增加1,最后一个加数是100;②第一个被加数是1,以后每次都使用上一次的和,最后一个被加数是1+... +99。

因此,可以使用循环结构解决这个问题。

使用循环结构解题。

可以设置两个整型变量add1、add2,分别用于存储被加数、加数。

令add1、add2的初值分别为1、2,每循环一次都需要进行——加运算add1+add2,然后将和保存到add1中并使add2的值增1以供下次循环使用。

循环条件的设置比较简单,只需设置一个整型变量counter,表示循环次数。

令counter的初值为1,每循环一次使counter的值增1(对于while和do-while语句,需要把对循环控制变量的设置放在循环体中。

对于for语句,即可以把对循环控制变量的设置放在表达式3中,也可以放在循环体中。

),当counter的值超过99时就结束循环,即循环条件是counter<=99。

根据以上分析,容易画出解决这个问题的流程图。

根据流程图,容易编写出程序(这里采用while语句)。

main()

{

intadd1=1,add2=2,counter=1,sum;

while(counter<=99)

{

add1=add1+add2;

add2=add2+1;

counter=counter+1;

}

sum=add1;

printf("sum=%d",sum);

}

程序的进一步简化:

main()

{

intadd1=1,add2=2;

while(add2<=100)

{

add1=add1+add2;

add2=add2+1;

}

printf("sum=%d",add1);

}

练习:

采用do-while语句和for语句改写该程序

【例2】由用户输入一个字符串,求该字符串中的所有字符的ASCII码值之和,并将结果输出到屏幕。

参考程序1:

#include

main()

{

intsum=0;

charc;

while

(1)

{

c=getchar();

if(c!

='\n')

sum=sum+c;

else

break;

}

printf("%d\n",sum);

}

参考程序2:

#include

main()

{

intsum=0;

charc;

while((c=getchar())!

='\n')

sum=sum+c;

printf("%d\n",sum);

}

参考程序3:

#include

main()

{

intsum=0;

charc;

for(sum=0;(c=getchar())!

='\n';sum=sum+c)

;

printf("%d\n",sum);

}

【例3】译密码。

为使电文保密,发报人往往按一定规律将其转换成密码,收报人再按约定的规律将其译回原文。

例如,可以按以下规律将电文变成密码:

将字母A变成字母E、a变成e、W变成A、X变成B、Y变成C、Z变成D,即变成其后的第4个字母,如下图所示。

字母按上述规律转换,非字母字符不变。

例如:

“China!

”会被转换为“Glmre!

”。

输入一行字符,要求输出其相应的密码。

分析:

对用户输入的字符串中的字符进行逐个扫描和相应的处理:

先读入第一个字符,判定它是否为大写字母或小写字母,若是,则将其值加4。

这时,对于由用户输入的A~V和a~v已变成其后的第4个字母;而对于由用户输入的W~Z和w~z却没有达到同样的效果,对这种情况还需作进一步处理,办法是使c减去26,这时对于由用户输入的W~Z和w~z就变成其后的第4个字母了。

第一个字符处理完后,再读入第二个字符,进行相应的处理……,如此反复,直到处理完用户

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1