第3章循环结构.docx

上传人:b****5 文档编号:3868643 上传时间:2022-11-26 格式:DOCX 页数:31 大小:77.69KB
下载 相关 举报
第3章循环结构.docx_第1页
第1页 / 共31页
第3章循环结构.docx_第2页
第2页 / 共31页
第3章循环结构.docx_第3页
第3页 / 共31页
第3章循环结构.docx_第4页
第4页 / 共31页
第3章循环结构.docx_第5页
第5页 / 共31页
点击查看更多>>
下载资源
资源描述

第3章循环结构.docx

《第3章循环结构.docx》由会员分享,可在线阅读,更多相关《第3章循环结构.docx(31页珍藏版)》请在冰豆网上搜索。

第3章循环结构.docx

第3章循环结构

第三章循环结构

在程序设计中,如果需要重复执行的某些操作,就要用到循环结构。

使用循环结构编程时,首先要明确2个问题,哪些操作需要重复执行?

这些操作在什么情况下重复执行?

它们分别对应循环体和循环条件,然后就可以选用C语言提供的3种循环语句:

while、do-while、for实现循环,这写循环语句我们在第一章“1、2C语言程序设计语法”和第二章“2.6字符类型”中也都见过,而第二章2、4节的用if语句和goto语句构成“直到型(无条件转移)”也叫循环结构。

3.1while语句

while是用来实现循环的语句,而且它的适用面很广。

其一般格式为:

while(表达式)

循环语句;

其执行的流程如图3.1所示。

当表达式的值为“真”时,循环执行,直到表达式的值为“假”,循环终止并继续执行while的下一条语句。

while语句的用法:

(1)while语句中的表达式可以是任意合法的表达式,表达式

循环体语句只能是一条语句。

(2)while语句的构成简单,只有一个表达式和一条循环体语句

循环体语句,分别对应循环的两个核心要素:

条件和循环体,可以直接把循环问题的分析设

计转换为语句实现。

While的下一条语句

(3)循环的实现一般包括4部分,即初始化、条件控图3.1while语句的执行流程

制、重复的操作以及通过改变循环变量的值最终

改变条件的真假性,使循环能正常结束。

当使用while语句时,由于它只有2个

成分(表达式和循环体语句),就需要另加初始化部分,第4部分while的循环体

语句中必须包含能最终改变循环条件真假性的操作。

例3.1从键盘输入一批学生的成绩,计算平均分,并统计不及格学生的人数。

这是一个累加求和的问题,将输入的成绩先累加,最后再除以学生的数量,算出平均分。

本题的难点在于确定循环条件,由于题目中没有给出学生的数量,不知道输入数据的个数,所以无法事先确定循环次数,这时需要自己设计循环条件,可以用一个特殊的数据作为正常输入数据的结束标志,由于成绩都是正数,就选用一个负数作为结束标志,因此,循环条件就是输入的数据grade>=0。

#include

intmain()

{intnum=0,fai=0;//num记录输入数据的个数,以便统计平均分;fai记录不及格人数

doublegrade,total=0;//grade存放输入的成绩,total保存成绩之和

printf("Entergrades:

\n");//输入提示

scanf("%lf",&grade);//输入第一个学生成绩

while(grade>=0)

{total=total+grade;//累加成绩

num++;//计数

if(grade<60)fai++;//不及格人数统计

scanf("%lf",&grade);//再读入一个新数据,为下次循环做准备

}

if(num!

=0)

{printf("Gradeverageis%.2f\n",total/num);//total/num是累加成绩/成绩个数=平均分

printf(“不及格学生的人数为(failures):

%d\n”,fai);

}

else

printf("Gradeaverageis0\n");

return0;

}

例3.2猴子吃桃问题,猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个,第二天早上又将剩下的桃子吃掉一半多一个。

以后每天早上都吃了前一天剩下的一半多一个,到第10天早上想再吃时,见只剩下一个桃子了,求第一天共摘下多少桃子。

程序编写如下:

#include//第10天是1,因为4的1半是2,多1个是3,第10天是1了

main()//第9天是(1+1)*2=4(1+1)*2=4是第9天的4

{intday=9,x1,x2=1;//x1前1天数,x2后1天数//第8天是(4+1)*2=10第8天10

while(day>0)//第7天是(10+1)*2=22第7天22

{//前一天桃子数是后一天桃子数加1后的2倍//第6天是(22+1)*2=46第6天46

x1=(x2+1)*2;//第5天是(46+1)*2=94第5天94

x2=x1;//第4天是(94+1)*2=190第4天190

day--;//第3天是(190+1)*2=382第3天382

}//第2天是(382+1)*2=7661534/2-1=766是第2天

printf("total=%d\n",x1);//第1天是(766+1)*2=1534(766+1)*2=1534是第1天

return0;

}

运行结果:

total=1534(也就是猴子第一天摘的桃子是1534个)

3.2do–while语句

do–while语句与while语句略有不同,它先执行循环体,后判断循环条件。

所以无论循环条件的值如何,至少会执行一次循环体,其一般形式如下:

do

{

循环体语句

}

While(表达式);

do–while语句的执行流程如图3.2所示,第一

次进入循环时,首先执行循环体语句,然后再检查循环

控制条件,即计算表达式,若值为“真”,继续循环,直循环体语句

到表达式的值为“假”,循环结束,执行do-while的下假

一条语句。

表达式

do-while语句的使用方法和while语句类似,语句真

中的表达式可以是任意合法的表达式,循环体语句只能

是一条语句;使用时要另加初始化部分,循环体语句必须

包含能最终改变条件真假的操作,例如例3.2中的day>0do-while的下一条语句

用--day来控制,到day减到不大于0时就结束了。

图3.2do-while语句流程图

do–while语句适用于先循环,后判断循环条件

的情况,一般在循环体的执行过程中明确循环控制条件,它每执行一次循环体后,再判断条件,以决定是否进行下一次循环。

例3.3求sn=a+aa+aaa+…+aa…a之值,其中a是一个数字,例如:

3+33+333+3333+33333(此时n是5),a和n由键盘输入。

#include

main()

{//a是位上的数如3,n是多少位,如33333是5位,tn是前个位数a,sn是后个位数aa

inta,n,i=1,tn=0,sn=0,z=0;//i是用做循环的

printf("a=:

");//输进位上的一个数

scanf("%d",&a);

z=a;

printf("n=:

");//要有多少位

scanf("%d",&n);

do

{tn=tn+a;//第一次tn是0,0+a是a,之后a*10为a0,第2次tn是a,a+a*10=aa……

sn=sn+tn;

a=a*10;

++i;

}

while(i<=n);

printf("a+aa+aaa+...=%d\n",sn);

printf("%d+%d%d+%d%d%d+%d%d%d%d+.....的前%d项和是=%d\n",

z,z,z,z,z,z,z,z,z,z,n,sn);

return0;

}

运行结果:

a=:

3

n=:

5

a+aa+aaa+…=37035

3+33+333+3333+……的前5项和是:

37035

注意:

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

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

例如,本例中while语句中若无大括弧,则while语句范围只到“tn=tn+a;”。

(2)在循环体中应有使循环趋向于结束的语句。

例如,本例中循环结束的条件是“i<=n”,因此在循环体中应该有使i增值以最终导致i>n的语句,这里用“++i;”语句来达到此目的。

如果无此语句,则i的值始终不改变,循环永不结束。

其实该例题用while语句也是一样的,大家可试试看。

一般情况下,用while语句和用do-while语句处理同一问题时,若二者的循环体部分是一样的,它们的结果也一样。

但在while后面的表达式一开始就为假(0值)时,两种循环的结果是不同的。

例如:

例3、4求1-10的累加和,用while和do-while循环比较

#include#include

main()main()

{intsum=0,i;{intsum=0,i;

scanf(“%d”,&i);scanf(“%d”,&i);

while(i<=10)do

{sum=sum+i;{sum=sum+i;

i++;i++;

}}

printf(“%d”,sum);while(i<=10);

printf(“%d”,sum);

}}

运行结果:

输入1运行结果:

输入1

5555

若输入大于10的数,结果就不一样了:

运行结果:

输入11运行结果:

输入11

011

这是因为此时对while语句循环来说,一次也不执行循环体(循环体”while(i<=10)”为假,所以结果为0,而对do-while循环来说则要执行一次循环体,因此结果得11。

可以得到结论:

当while后面的表达式的第一次的值为”真”时,两种循环得到的结果相同。

否则,二者结果不相同(指二者具有相同的循环体的情况)。

3.3for语句

第二章例2、2是把华氏温度100°F转换成相应的摄氏温度的程序;如果要求输出一张华氏-摄氏温度转换表,例如:

将华氏温度30-35°F之间的每一度都转换成相应的摄氏温度后输出,就要反复做多次温度转换计算和输出。

在重复操作的过程中,温度每增加1°F,都会使用同一个计算公式和同一个程序过程。

对于这类重复执行的问题,采用C语言的循环结构for语句,可以轻而易举地解决。

例3.5输出一张华氏-摄氏温度转换表,华氏温度取值范围是[lower,upper],每次增加1°F。

计算公式如第二章例2、2中所示。

式中,c表示摄氏温度,f表示华氏温度。

#include

intmain()

{//fahr表示华氏温度,celsius为摄氏温度,lower为华氏温度下限,upper为上限

intfahr,lower,upper;

doublecelsius;

printf("Enterlower输入华氏温度下限:

");

scanf("%d",&lower);

printf("Enterupper输入华氏温度上限:

");

scanf("%d",&upper);

printf("(fahr)华氏温度转换成(celsius)摄氏温度是:

\n");

for(fahr=lower;fahr<=upper;fahr++)

{celsius=(5.0/9.0*(fahr-32));

printf("华氏温度%d=摄氏温度%6.1lf\n",fahr,celsius);

}

}

输出结果:

Enterlower:

30

Enwerlower:

35

(fahr)华氏温度转换成(celsius)摄氏温度是:

华氏温度30=摄氏温度-1.1

华氏温度31=摄氏温度-0.6

华氏温度32=摄氏温度0.0

华氏温度33=摄氏温度0.6

华氏温度34=摄氏温度1.1

华氏温度35=摄氏温度1.7

将程序的2次输入,改成一次输入,程序如下:

#include

intmain()

{intfahr,lower,upper;

doublecelsius;

printf("输入华氏温度的下限(lower)和上限(upper):

");

scanf("%d,%d",&lower,&upper);//下限值(30)和上限(35)一起输入,中间用”,”分开。

printf("fahrcelsius:

\n");

for(fahr=lower;fahr<=upper;fahr++)

{celsius=(5.0/9.0*(fahr-32));

printf("%d%6.1lf\n",fahr,celsius);

}

}

程序设计流程如图3.3所示。

程序中用for语句实现循环,针对华氏温度在[lower,upper]内的每一个值,使用温度转换公式算出摄氏温度,并输出华氏温度和摄氏温度。

温度的转换和输出是一个重复的操作,华氏温度每次增加1°F,直到超出给定的上限upper循环结束。

for语句中的fahr++相当于fahr=fahr+1,即fahr的值增加1。

在C语言中,for语句被称为循环语句,它可以实现C语言的重复执行。

for语句的一般形式为:

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

for语句中,用两个分号分隔3个表达式,但for的后面没有分号,因为for与其后的循环语句合起来作为一条完整的语句。

for语句的执行流程如图2、3所示,先计算表达式1;再判断表达式2;若值为“真”,则执行循环体语句,并接着计算表达式3,然后继续循环;若为“假”,则结束循环,继续执行for的下一条语句。

↓↓

fahr=lower表达式1

↓↓

fahr<=upper?

表达式2

↓真↓

转换计算和输出循环体语句

↓↓

fahr++表达式3

for的下一条语句

图3.3例2.7程序中for语句的执行流程图图3.4for语句执行流程图

for语句中的3个表达式以及循环体语句的执行顺序和书写顺序有所不同,计算表达式3在执行循环体语句之后。

图3.4清楚地表明:

在fir语句的执行过程中。

表达式2、循环体语句和表达式3将重复执行,而表达式1只在进入循环前执行一次。

也就是说,for语句中的表达式1只执行一次。

在for语句中,常常通过改变和判断某个变量的值来控制循环的执行,这样的变量称为循环控制变量,简称循环变量。

例如:

华氏温度fahr就是循环变量,for语句的3个表达式分别对它赋初值、判断其值和改变其值。

for语句中3个表达式可以是任意合法的表达式,循环体语句只能是一条语句。

如果循环体语句由多条语句组成,必须用大括号把它们括起来,组成一条复合语句。

在C语言中,仅由一个分号(;)构成的语句称为空语句,它什么也不做。

如果将上述for语句改为:

for(fahr=lower;fahr<=upper;fahr++);//分号代表空语句

{celsius=(5.0/9.0*(fahr-32));

printf("%d%6.1lf\n",fahr,celsius);

}

则循环体语句就是空语句,真正要反复执行的温度的转换和输出都被当做for的下一条语句。

这也是初学者常犯的错误,程序运行时系统同样不会有任何出错提示。

不要在for语句中随意加分号(;)。

n

例3、6输入一个正整数n,求∑i

i=1

这是一个反复求和的过程,在数学上可以表示为:

sum=1+2+3…+n,但无法直接表示成C语言的表达式。

为了解决这个问题,首先抽取出具有共性的算式(称为循环不变式):

sum=sum+i;sum是累加和,其初值为0。

该算式重复n次,同时i从1变到n,就实现了从1加到n。

设i为循环变量,确定for语句中的3个表达式和循环体语句:

(1)指定循环起点的表达式1:

i=1

(2)给出循环条件的表达式2:

i<=n(n是循环终点)

(3)设置循环步长的表达式3:

i++

(4)循环体语句:

sum=sum+i

//计算1+2+3+…+n

#include

intmain()

{inti,n,sum;

printf("Entern:

");

scanf("%d",&n);

sum=0;

for(i=1;i<=n;i++)

{

sum=sum+i;//反复累加i的值

}

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

return0;

}

运行结果:

Entern:

100

Sumofnumbersfrom1to100is5050

虽然循环次数由输入的n决定,但就for语句而言,n的值在循环前已经决定。

由于sum=sum+i是在原累加和sum的基础上一步一步地累加i的值,所以在循环开始前,必须置为0,以保证sum在0的基础上累加,这个步骤千万不能遗漏。

循环体语句向右缩进对齐,可以明确标识循环体的范围,这和if语句的风格一致。

111

例3、7输入一个正整数n,计算1-+-+…的前n项之和

357

//计算1-1/3+1/5-1/7+…共n项之和

#include

intmain()

{intdenominator,flag,i,n;//denominator表示分母,falg是一个改变符号的标志,i,n循环次数

doubleitem,sum;//item是第i项的值,sum是累加和

printf("Entern:

");//提示

scanf("%d",&n);//输入一个整数,要计算多少项

flag=1;//表示第一项的符号

denominator=1;//表示第i项的分母,初始为1,视为1/1

sum=0;//置累加和sum的初值为0

for(i=1;i<=n;i++)

{item=flag*1.0/denominator;//计算第i项的值

sum=sum+item;//累加第i项的值

flag=-flag;//改变符号,为下一次循环做准备

denominator=denominator+2;//分母逐项加2

}

printf("sum=%f\n",sum);//输出各项的累加和

return0;

}

运行结果:

Entern:

2

sum=0.666667

3.4循环嵌套

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

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

while语句、do-while语句、for语句都可实现循环嵌套,如:

while()for(;;)

{{

..

..

..

while()while()*

{...}{...}***

}}*****

等等。

*******

*****

例3.8打印如图3.5的图形***

#include*

voidmain()图3.5星号图形

{inti,j,k;//定义变量,用来控制循环

for(i=0;i<=3;i++)//该循环用来输出上面4行*号

{for(j=0;j<=2-i;j++)//第一次输出3个空格,第二次i加了1,输出2个空格

printf("");//显然第三次输出一个空格,第四次不输出空格

for(k=0;k<=2*i;k++)//第一次输出一个*号,第二次k加了1,输出3个*号

printf("*");//显然第三次输出5个*号,第四次输出7个*号

printf("\n");

}

for(i=0;i<=2;i++)//该循环输出下面3行*号

{for(j=0;j<=i;j++)//第一次输出1个空格,第二次输出2个空格,第三次输出3个空格

printf("");

for(k=0;k<=4-2*i;k++)//第一次i是0,输出5个*号,第二次输出3个*号,三次1个*

printf("*");

printf("\n");

}

return;

}

例3.9输出小九九

#include

main()

{inti,j;

for(i=1;i<=9;i++)

{

for(j=1;j<=i;j++)

{

printf("%d*%d=%d",j,i,j*i);

if(i==j)

printf("\n");

}

}

return0;

}

运行结果:

1*1=1

1*2=22*2=4

1*3=32*3=63*3=9

1*4=42*4=83*4=124*4=16

1*5=52*5=103*5=154*5=205*5=25

1*6=62*6=123*6=184*6=245*6=306*6=36

1*7=72*7=143*7=214*7=285*7=356*7=427*7=49

1*8=82*8=163*8=244*8=325*8=406*8=487*8=568*8=64

1*9=92*9=183*9=274*9=365*9=456*9=547*9=638*9=729*9=81

例3.9五世纪末,我国古代数学家张丘建在他编写的《算经》一书里提出一个不定方程问题,即有名的“百钱买百鸡”问题。

说:

一只公鸡值5钱,一只母鸡值3钱,三只小鸡值1钱。

用百钱买百只鸡,问公、母、小鸡各能买多少只?

我们在这里设:

公鸡、母鸡、小鸡各为x、y、z个,显然x的变化范围在0和20之间,因为百钱全买公鸡也只不过买20只,同理y的变化范围在0~34之间,所得的不定方程为:

5x+3y+z/3=100既然是不定方程,所以其解也不只是一组,程序如下:

#include

intmain()

{

intx,y,z;

for(x=0;x<=20;++x)

{

for(y=0;y<=33;++y)

{//当x=0,y=25时,z自然=75,条件if((z%3==0)&&((5*x+3*y+z/3)==100))就成立,就打印公、母、小鸡数

//再循环x=4,y=18,z自然=78,…………就成立,………

z=100-x-y;

if((z%3==0)&&((5*x+3*y+z/3)==100))

printf("

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

当前位置:首页 > 小学教育 > 数学

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

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