C语言程序设计(第2版)中课件_第1页
C语言程序设计(第2版)中课件_第2页
C语言程序设计(第2版)中课件_第3页
C语言程序设计(第2版)中课件_第4页
C语言程序设计(第2版)中课件_第5页
已阅读5页,还剩134页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、C语言程序设计(第2版)第1页,共139页。第五章循环结构程序设计第2页,共139页。 本章要点 循环的基本概念 不同形式的循环控制 多重循环问题 第3页,共139页。5.1程序中需要用循环结构5.2用while语句和do-while语句实现循环5.3用for 语句实现循环 5.4循环的嵌套5.5用break语句和continue语句改变循环状态5.6几种循环的比较5.7程序举例5.8提高部分 主要内容第4页,共139页。 5.1 程序中需要用循环结构什么是循环?为什么要使用循环?问题1:问题2:求学生平均成绩 分数相加后除以课数在许多问题中需要用到循环控制。循环结构就是用来处理需要重复处理的

2、问题的,所以又称重复结构。它和顺序结构、选择结构共同作为各种复杂程序的基本构造单元。循环分为两种:无休止循环和有终止循环构成有效循环的条件:循环体和循环结束条件第5页,共139页。5.2 用while语句和do-while语句实现循环 5.2.1 用while语句实现循环while语句用来实现“当型”循环结构一般形式: while (表达式) 语句 当表达式为非0值时,执行while语句中的内嵌语句。其特点是:先判断表达式,后执行循环体,即内嵌语句。第6页,共139页。例题 5.1求1+2+3+100的和解题思路(1)开始时使sum的值为0,被加数i第一次取值为1。开始进入循环结构。(2)判别

3、“i100”条件是否满足,由于i小于100,因此“i100”的值为真。所以应当执行其下面矩形框中的操作。(3)执行sum=sum+i,此时sum的值变为1了,然后使i的值加1,i的值变为2了,这是为下一次加2作准备。流程返回菱形框。(4)再次检查“i100”条件是否满足,由于i的值为2,小于100,因此“i100”的值仍为真,所以应执行其下面矩形框中的操作。(5)执行sum=sum+i,由于sum的值已变为1,i的值已变为2,因此执行sum=sum+i后sum的值变为3。再使i的值加1,i的值变为3。流程再返回菱形框。(6)再次检查“i100”条件是否满足,如此反复执行矩形框中的操作,直到i的

4、值变成了100,把i加到sum中,然后i又加1变成101了。当再次返回菱形框检查“i100”条件时,由于I已是101,大于100,“i100” 的值为假,不再执行矩形框中的操作,循环结构结束。5.2 用while语句和do-while语句实现循环 第7页,共139页。#include void main() int i,sum=0;/* sum是用来存放累加和的变量 */ /* 初值为0 */ i=1; while (i=100)/* 当I小于或等于100时 */* 执行下面花括号中的复合语句 */ sum=sum+i;/* 将i的当前值累加到变量sum中 */ i+;/* 使i的值加1 */

5、 printf(%dn,sum); 说明:(1)循环体如果包含一个以上的语句,应该用花括号括起来,以复合语句形式出现.(2)在循环体中应有使循环趋向于结束的语句。运行结果: 5050编写程序5.2 用while语句和do-while语句实现循环 第8页,共139页。5.2 用while语句和do-while语句实现循环 5.2.2 用do-while语句实现循环 do-while语句的特点:先执行循环体,然后判断循环条件是否成立。执行过程:先执行一次指定的循环体语句,然后判别“表达式”,当表达式的值为非0(“真”) 时,返回重新执行循环体语句,如此反复,直到表达式的值等于0 (“假”)为止,此

6、时循环结束。while语句和do-while语句的关系:同一个问题既可以用while循环处理,也可以用do-while循环来处理。二者是可以互相转换的。一般形式: do 循环体语句 while(表达式);第9页,共139页。例题 5.2 求1+2+3+100的和#include void main() int i,sum=0; i=1; do /* 在循环开始时不检查条件,先执行一次循环体 */ sum=sum+i; i+; while(i=100); printf(%dn,sum); 运行结果: 5050说明:可以看到,结果和例5.1完全相同。编写程序5.2 用while语句和do-whil

7、e语句实现循环 第10页,共139页。例题 5.3 募集慈善基金10000元,有若干人捐款,每输入一个人的捐款数后,计算机就输出当时的捐款总和。当某一次输入捐款数后,总和达到或超过10000元时,即宣告结束,输出最后的累加值。解题思路解此题的思路是设计一个循环结构,在其中输入捐款数,求出累加值,然后检查此时的累加值是否达到或超过预定值,如果达到了,就结束循环操作。5.2 用while语句和do-while语句实现循环 第11页,共139页。#include void main() float amount,sum=0; /*变量sum用来存放累加和*/ do scanf(%f,&amount)

8、;/*输入一个捐款金额*/ sum=sum+amount; /*求出当前的累加和*/ while(sum10000);/*如未达10000元继续循环*/ printf(sum=%9.2fn,sum);运行结果:1000 (输入捐款额)18501500260025001200sun= 10650.00说明:设计循环结构,要考虑两个问题:一是循环体,二是循环结束条件。注意while循环中判断的条件是循环继续的条件,而不是结束条件。5.2 用while语句和do-while语句实现循环 编写程序第12页,共139页。5.3 用for语句实现循环5.3.1 for语句的一般形式和执行过程C语言中的fo

9、r语句使用最为灵活,不仅可以用于循环次数已经确定的情况,而且可以用于循环次数不确定而只给出循环结束条件的情况,它完全可以代替while语句。一般形式: for(表达式1;表达式2;表达式3) 语句第13页,共139页。5.3 用for语句实现循环5.3.1 for语句的一般形式和执行过程 for语句的执行过程: (1) 先求解表达式1。 (2) 求解表达式2,若其值为真(值为非0),则执 行for语句中指定的内嵌语句,然后执行下 面第(3)步。若为假(值为0),则结束循环, 转到第(5)步。 (3) 求解表达式3。 (4) 转回上面第(2)步骤继续执行。 (5) 循环结束,执行for语句下面的

10、一个语句。第14页,共139页。for语句最简单的形式:for(循环变量赋初值;循环条件;循环变量增值) 例如: for(i=1;i=100;i+) sum=sum+i;相当于: i=1; while(i=100) sum=sum+i;i+; 5.3 用for语句实现循环5.3.1 for语句的一般形式和执行过程第15页,共139页。5.3 用for语句实现循环5.3.2 for循环程序举例 国王的小麦。相传古代印度国王舍罕要褒赏他的聪明能干的宰相达依尔(国际象棋的发明者),国王问他要什么?达依尔回答说:“国王只要在国际象棋的棋盘第1个格子中放1粒麦子,第2个格子中放2粒麦子,第3个格子中放4

11、粒麦子,以后按此比例每一格加一倍,一直放到第64格(国际象棋的棋盘8*8=64格),我感恩不尽,其他什么都不要了。”国王想,这有多少!还不容易!让人扛来一袋小麦,但不到一会儿全用没了,再来一袋很快又用完了。结果全印度的粮食全部用完还不够。国王纳闷,怎样也算不清这笔账。现在我们用计算机来算一下。例题 5.4第16页,共139页。解题思路麦子的总粒数是:分别计算出每一格的麦子粒数,把它们加起来,就得到总粒数。据估算,1 小麦约有1.42 粒,可以计算出小麦的体积。可以用for语句实现循环。5.3 用for语句实现循环第17页,共139页。#include void main() double p=

12、1, t=1, v; int i; for(i=1; i64; i+) /* 执行63次循环 */ p = p * 2; /* p是当前一个格子中的麦子粒数 */ t = t + p; /* t是当前麦子总粒数 */ v = t / 1.42e8; /* v是总体积 */ printf(total=%en,t); /* 用指数形式输出麦子总粒数 */ printf(volume=%en,v);/* 用指数形式输出麦子总体积 */运行结果:total=1.844674e+019volnme=1.299066e+011编写程序5.3 用for语句实现循环第18页,共139页。说明: 变量i用来控制

13、循环的次数,开始时i=1,在完成第1次循环后,i的值加1变为2,由于264,所以执行第2次循环,依此类推,当i变到63时,执行最后一次循环,i再变为64,由于i不再小于64了,不再执行循环。接着计算体积,输出结果。5.3 用for语句实现循环第19页,共139页。5.3 用for语句实现循环 人口增长预测。据2005年末统计,我国人口为130756万人,如果人口的年增长率为1%,请计算到哪一年中国总人口超过15亿。例题 5.5解题思路计算人口增长和计算存款利息的公式是相同的。假设原来人口为 ,则一年后的人口:其中r是年增长率。用此公式依次计算出每年的人口,每算出一年的人口后就检查一下是否达到或

14、超过15亿?如果未达到或超过15亿,就再计算下一年的人口,直到某一年的人口达到或超过15亿为止。第20页,共139页。编写程序5.3 用for语句实现循环#include void main() double p=1.30756e9,r=0.01; int y; for(y=2006; p1.5e9; y+) /* 赋值号两侧的变量p代表不同含义 */ p=p*(1+r); printf(year=%d,p=%en,y-1,p); 运行结果:year=2019,p=1.503007e+009第21页,共139页。说明:注意区分变量p在不同阶段中的不同含义。 y代表年份。循环体中只有一个语句,用

15、来计算从2006年开始的各年的人口数。在for语句中设定的循环条件是p15亿,当某一年的p达到或超过15亿,就停止循环,输出年份和当年的人口数。由于在最后结束循环前y又加了1,因此在输出年份时应输出y-1的值而不是y的值。5.3 用for语句实现循环第22页,共139页。5.3 用for语句实现循环5.3.2 for循环程序举例 一个变量开始时有一初值,通过一定的运算,可以推算出一个新的值,再从这个新值又推出下一个新值,即不断用计算出的新值去取代原有的值,这种方法称为迭代。上面的计算公式p*(1+r)称为迭代公式。迭代算法一般是用循环来实现的。迭代是一种常用的算法,用人工实现很麻烦,而用计算机

16、实现却十分方便。第23页,共139页。5.4 循环的嵌套一个循环体内又包含另一个完整的循环结构称为循环的嵌套。内嵌的循环中还可以嵌套循环,这就是多层循环。三种循环(while循环、do-while循环和for循环)可以互相嵌套。第24页,共139页。5.4 循环的嵌套下面几种都是合法的形式:(1) while( ) (2) do (3) for(;) while( ) do for(;) while( ); while( );第25页,共139页。5.4 循环的嵌套(4) while( ) (5) for(;) (6) do do while( ) for(;) while( ) while(

17、 ) 第26页,共139页。5.5 提前结束循环5.5.1 用break语句提前退出循环 break语句可以用来从循环体内跳出循环体,即提前结束循环,接着执行循环下面的语句。一般形式: break;说明:break语句不能用于循环语句和switch语句之外的任何其他语句中。 第27页,共139页。 统计各班级的学生的平均成绩。已知各班人数不等,但都不超过30人。编一个程序能处理人数不等的各班学生的平均成绩。例题 5.6解题思路 如果各班人数相同,问题比较简单,只需用一个for语句控制即可: for(i=1;i31;i+) 但是现在有的班不足30人,应当设法告诉计算机本班的人数,使程序也能统计出

18、该班的平均成绩。可以约定,当输入的成绩是负数时,就表示本班数据已结束(一般情况下成绩不会是负数)。在程序接收到一个负的分数时就提前结束循环,计算出本班平均成绩。 用break语句可以用来实现提前结束循环。5.5 提前结束循环第28页,共139页。编写程序5.5 提前结束循环#include void main() float score,sum=0,average; int i,n; for(i=1; i31; i+) scanf(%f,&score);/* 输入一个学生的成绩 */ if(score0) break; /* 如果输入负值,则跳出循环 */ sum=sum+score; /*

19、把该成绩累加到sum */ n=i-1; /* 学生数应是i-1 */ average=sum/n; /* 计算平均成绩 */ /* 输出学生数和平均成绩 */ printf(n=%d,average=%7.2fn,n,average); 运行结果:100 (输入一个学生成绩)8070-1 (输入负数,表示本班数据结束)n=3,average= 90.00第29页,共139页。说明: 如果一个班有30人,则输入完30人的成绩后累计总分后自动结束循环,不必再输入负数作为结束标志。在结束循环后i的值等于31(因为执行完30次循环后,i再加1,变成31,此时才终止循环),因此学生数n应该等于i-1。

20、 如果一个班人数少于30人,则在输入完全班学生的成绩后,输入一个负数,此时程序就跳过循环体其余的语句,也不再继续执行其余的几次循环。直接跳到循环下面的语句(n=i-1;)继续执行。刚输入的数不进行累加(不执行sum=sum+score;)。注意此时i的值,假如已输入了25个有效分数,在第26次循环时输入一个负数,此时i的值是26,而学生数n应是i-1。5.5 提前结束循环第30页,共139页。5.5 提前结束循环5.5.2 用continue语句提前结束本次循环continue语句作用为结束本次循环,即跳过循环体中下面尚未执行的语句,接着进行下一次是否执行循环的判定.一般形式: continu

21、e;第31页,共139页。5.5 提前结束循环5.5.2 用continue语句提前结束本次循环 continue语句和break语句的区别: continue语句只结束本次循环,而不是终止整个循环的执行。while(表达式1) if(表达式2) continue; 第32页,共139页。 continue语句和break语句的区别: break语句则是结束整个循环过程,不再判断执行循环的条件是否成立。 while(表达式1) if(表达式2) break; 5.5 提前结束循环5.5.2 用continue语句提前结束本次循环第33页,共139页。 输入一个班全体学生的成绩,把不及格的学生成

22、绩输出,并求及格学生的平均成绩。例题 5.7解题思路 在进行循环中,检查学生的成绩,把其中不及格的成绩输出,然后跳过后面总成绩的累加和求平均成绩的语句。用continu语句即可处理此问题。5.5 提前结束循环第34页,共139页。#include void main() float score,sum=0,average; int i,n=0; for(i=1; i6; i+) /* 假设有5个学生 */ printf(please enter score:); scanf(%f,&score); /* 输入学生成绩 */ if(score60) /* 如不及格 */ /* 输出不及格的成绩

23、*/printf(Fail:%7.2fn,score); continu; /* 跳过下面的语句,结束本次循环 */ sum=sum+score; n=n+1; /* n是用来统计及格学生人数 */ average=sum/n; /* 及格学生平均分数 */);/* 输出及格学生人数和平均分数 */ printf(nn=%d,average=%7.2fn,n,average 运行结果:please enter score:89please enter score:56Fail:56please enter score:76please enter score:58Fail:58please e

24、nter score:98n=3 average=87.675.5 提前结束循环编写程序第35页,共139页。说明: 为减少输入量,本程序只按5个学生处理。在输入不及格学生成绩后,输出该成绩,然后跳过循环体中未执行的语句,即不参加累计总分sum,也不累计合格学生数n。但是,继续执行后面的几次循环。5.5 提前结束循环第36页,共139页。5.6 几种循环的比较(1)三种循环都可以用来处理同一问题,一般情况下它们可以互相代替。 (2)在while循环和do-while循环中,只在while后面的括号内指定循环条件,因此为了使循环能正常结束,应在循环体中包含使循环趋于结束的语句(如i+,或i=i+

25、1等)。第37页,共139页。5.6 几种循环的比较for循环可以在表达式3中包含使循环趋于结束的操作,甚至可以将循环体中的操作全部放到表达式3中。因此for语句的功能更强,凡用while循环能完成的,用for循环都能实现。(3)用while和do-while循环时,循环变量初始化的操作应在while和do-while语句之前完成。而for语句可以在表达式1中实现循环变量的初始化。第38页,共139页。5.6 几种循环的比较(4) while循环、dowhile循环和for循环,都可以用break语句跳出循环,用continue语句结束本次循环 。 第39页,共139页。 有一对兔子,出生后第

26、3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子。假设所有兔子都不死,问40个月的兔子总数为多少?例题 5.8解题思路5.7 程序举例 第几个月小兔子对数中兔子对数老兔子对数兔子总数110012010131012411135212563238753513第40页,共139页。可以看到每个月的兔子总数依次为 1,1,2,3,5,8,13这就是有名的费波那西(Fibonacci)数列。 5.7 程序举例 第41页,共139页。编写程序5.7 程序举例 #include void main() long int f1,f2; int i; f1=1;f2=1; for(i=1; i

27、=20; i+) printf(%12ld %12ld ,f1,f2); if(i%2=0) printf(n); f1=f1+f2; f2=f2+f1; 运行结果: 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 57022887 9227465 14930352 24157817 39088169 63245986 1023341

28、55 第42页,共139页。说明:(1)变量f1和f2用长整型,在printf函数中输出格式符用“%12ld”,而不是用“%12d”,这是由于在第23个数后,整数值已超过整数最大值32767,因此必须用长整型变量才能容纳,并用“%ld”格式输出。(2)if语句的作用是使输出4个数后换行。i是循环变量,当i为偶数时换行,而i每增值1,就要计算和输出2个数(f1,f2),因此i每隔2换一次行相当于每输出4个数后换行输出。5.7 程序举例 第43页,共139页。给一个整数m,判断它是否素数。例题 5.9解题思路5.7 程序举例 让m被i(i由2变到k= )除,如果m能被某一个i(2k之间的任何一个整

29、数)整除,则m必然不是素数,不必再进行下去。此时的i必然小于或等于k;如果m不能被2-k之间的任一整数整除,则m应是素数,此肘在完成最后一次循环后,使i再加1,因此i的值就等于k+1,这时才终止循环。在循环结束之后判别i的值是否大于或等于k+1,若是,则表明未曾被2-k之间任一整数整除过,因此输出“是素数”。第44页,共139页。#include #include void main() int m,i,k; printf(“please enter a integer number:”); scanf(“%d”,&m); /* 输入一个整数m */ k=(int)sqrt(m); /* 对m

30、求平方根,再取整 */ for (i=2;ik) printf(%d is a prime number.n,m); else printf(%d is not a prime number.n,m); 编写程序5.7 程序举例 运行结果: please enter a integer number: 1717 is a prime number.第45页,共139页。 译密码。为使电文保密,往往按一定规律将其转换成密码,收报人再按约定的规律将其译回原文。例题 5.10解题思路5.7 程序举例 可以按以下规律将电文变成密码: 将字母A变成字母E,a变成e,即变成其后的第4个字母,W变成A,X变

31、成B,Y变成C,Z变成D。第46页,共139页。#include void main() char c; while(c=getchar()!=n) /* 判定c是否字母 */ if(c=a & c=A & cZ & cz) c=c-26; printf(%c,c); printf(n);编写程序5.7 程序举例 运行结果: China! Glmre! 第47页,共139页。说明:内嵌的if语句不能写成: if( cZ| cz) /* 请和程序笫7行比较 */ c=c-26;因为如果所有小写字毋都满足“cZ”的条件,从而也都执行“c=c-26;”语句,这就会出错。因此必须限制其范围为“cZ &

32、 c=Z+4”,即原字母为W到Z。只有符合此条件才减26,否则,不应按此规律转换。5.7 程序举例 第48页,共139页。5.8 提高部分5.8.1 while和 do-while循环的比较凡是能用while循环处理,都能用dowhile循环处理。dowhile循环结构可以转换成while循环结构。 在一般情况下,用while语句和用do-while语句处理同一问题时,若二者的循环体部分是一样的,它们的结果也一样。但是如果while后面的表达式一开始就为假(0值)时,两种循环的结果是不同的。第49页,共139页。例5.11 while和do-while循环的比较 (1) (2) #includ

33、e #include void main ( ) void main( ) int sum=0,i; int sum=0,i; scanf(“%d,&i); scanf(”%d,&i); while (i=10) do sum=sum+I; sum=sum+i; i+; i+; while (i=10); printf(“sum=%dn”, printf(“sum=%dn”, sum); sum); 运行结果:1 sum=55 再运行一次: 11sum=0运行结果:1 sum=55 再运行一次: 11sum=11说明:当while后面的表达式的第一次的值为“真”时,两种循环得到的结果相同。否则

34、,二者结果不相同。5.8 提高部分第50页,共139页。5.8 提高部分5.8.2 for语句的各种形式for语句相当灵活,形式变化多样: (1) for语句的一般形式中的“表达式1”可以省略,此时应在for语句之前给循环变量赋初值。注意省略表达式1时,其后的分号不能省略。如: for(;i=100;i+) sum=sum+i; 执行时,跳过“求解表达式1”这一步,其他不变。第51页,共139页。(2) 如果表达式2省略,即不判断循环条件,循环无终止地进行下去。也就是认为表达式2始终为真。如: for(i=1; ;i+) sum=sum+i; 表达式1是一个赋值表达式,表达式2空缺。它相当于:

35、 i=1; while(1) sum=sum+1;i+;5.8 提高部分5.8.2 for语句的各种形式第52页,共139页。(3) 表达式3也可以省略,但此时程序设计者应另外设法保证循环能正常结束。如: for(i=1;i=100;) sum=sum+i;i+; 在上面的for语句中只有表达式1和表达式2,而没有表达式3。i+的操作不放在for语句的表达式3的位置处,而作为循环体的一部分,效果是一样的,都能使循环正常结束。5.8 提高部分5.8.2 for语句的各种形式第53页,共139页。(4) 可以省略表达式1和表达式3,只有表达式2,即只给循环条件。如: for(;i=100;) wh

36、ile(i=100) sum=sum+i; 相当于 sum=sum+i; i+; i+; 在这种情况下,完全等同于while语句。可见for语句比while语句功能强,除了可以给出循环条件外,还可以赋初值,使循环变量自动增值等。5.8 提高部分5.8.2 for语句的各种形式第54页,共139页。(5) 3个表达式都可省略,如: for(; ;) 语句相当于 while(1) 语句 即不设初值,不判断条件(认为表达式2为真值),循环变量不增值。无终止地执行循环体。5.8 提高部分5.8.2 for语句的各种形式第55页,共139页。(6) 表达式1可以是设置循环变量初值的赋值表达式,也可以是与

37、循环变量无关的其他表达式。如: for (sum=0;i=100;i+) sum=sum+i;表达式3也可以是与循环控制无关的任意表达式。5.8 提高部分5.8.2 for语句的各种形式第56页,共139页。表达式1和表达式3可以是一个简单的表达式,也可以是逗号表达式,即包含一个以上的简单表达式,中间用逗号间隔。如: for(sum=0,i=1;i=100;i+) sum=sum+i;或 for(i=0,j=100;i=j;i+,j-) k=i+j;表达式1和表达式3都是逗号表达式,各包含两个赋值表达式,即同时设两个初值,使两个变量增值。 5.8 提高部分5.8.2 for语句的各种形式第57

38、页,共139页。 在逗号表达式内按自左至右顺序求解,整个逗号表达式的值为其中最右边的表达式的值。如: for(i=1;i=100;i+,i+) sum=sum+i;相当于 for(i=1;i=100;i=i+2) sum=sum+i;5.8 提高部分5.8.2 for语句的各种形式第58页,共139页。(7) 表达式一般是关系表达式(如i=100)或逻辑表达式(如ab & xy),但也可以是数值表达式或字符表达式,只要其值为非零,就执行循环体。5.8 提高部分5.8.2 for语句的各种形式第59页,共139页。 for(i=0;(c=getchar()!=n;i+=c); 在表达式2中先从终

39、端接收一个字符赋给c,然后判断此赋值表达式的值是否不等于n(换行符),如果不等于n,就执行循环体。注意:此for语句的循环体为空语句,把本来要在循环体内处理的内容放在表达式3中,作用是一样的。可见for语句功能强,可以在表达式中完成本来应在循环体内完成的操作。5.8 提高部分5.8.2 for语句的各种形式第60页,共139页。 for( ;(c=getchar()!=n;) printf(%c,c); for语句中只有表达式2,而无表达式1和表达式3。其作用是每读入一个字符后立即输出该字符,直到输入一个“换行”为止。请注意,从终端键盘向计算机输入时,是在按Enter键以后才将一批数据一起送到

40、内存缓冲区中去的。运行情况:Computer (输入)Computer (输出)而不是Ccoommppuutteerr5.8 提高部分5.8.2 for语句的各种形式第61页,共139页。注意: C语言中的for语句比其他语言(如BASIC,PASCAL)中的FOR语句功能强得多。可以把循环体和一些与循环控制无关的操作也作为表达式1或表达式3出现,这样程序可以短小简洁。但过分地利用这一特点会使for语句显得杂乱,可读性降低,最好不要把与循环控制无关的内容放到for语句中。5.8 提高部分5.8.2 for语句的各种形式第62页,共139页。第六章利用数组处理批量数据第63页,共139页。问题:

41、给一组数排序,这组 数该 如何存放呢? 这些数据如何存放才便于排序82945637617188888888881111111111111118888888888这便是本章所要解决的问题第64页,共139页。 本章要点掌握一维、二维数组的定义和引用方法、存储结构和初始化方法。掌握有关一维数组的有关算法掌握数组的运算。第65页,共139页。主要内容6.1 为什么要用数组6.2 定义和引用一维数组6.3 二维数组的定义和引用6.4 字符数组6.5 提高部分第66页,共139页。6.1 为什么要用数组 C语言为这些数据,提供了一种构造数据类型:数组。所谓数组就是一组具有相同数据类型的数据的有序集合。一

42、个班学生的学习成绩一行文字一个矩阵这些数据的特点是:1、具有相同的数据类型2、使用过程中需要保留原始数据第67页,共139页。1.一维数组的定义格式为:类型说明符 数组名常量表达式;例如: int a10; 它表示定义了一个整形数组,数组名为a,此数组有10个元素。6.2 定义和引用一维数组6.2.1 定义一维数组说明: 1.数组名定名规则和变量名相同,遵循标识符定名规则。第68页,共139页。2.在定义数组时,需要指定数组中元素的个数,方括弧中的常量表达式用来表示元素的个数,即数组长度。3.常量表达式中可以包括常量和符号常量,但不能包含变量。也就是说,C语言不允许对数组的大小作动态定义,即数

43、组的大小不依赖于程序运行过程中变量的值。第69页,共139页。例如: int n; scanf(“%d,&n); /*在程序中临时输入数 组的大小 */ int an;数组说明中其他常见的错误: float a0;/* 数组大小为0没有意义 */ int b(2)(3); /* 不能使用圆括号 */ int k, ak; /* 不能用变量说明数组大小*/ 第70页,共139页。注意:定义数组时用到的“数组名常量表达式” 和引用数组元素时用到的“数组名下标” 是有区别的。例如 int a10; t=a6; 6.2 一维数组的定义和引用6.2.2 引用一维数组元素1.数组元素的引用方式:数组名下标

44、下标可以是整型常量或整型表达式。例如: a0=a5+a7-a2*3第71页,共139页。2.一维数组元素引用的程序实例例题 6.1 引用数组元素。利用循环给数组元素a0a9赋值为09,然后按逆序输出各元素的值解题思路 循环给数组元素a0 a9赋值09,这样,然后按a9到a0的顺序输出各元素的值。第72页,共139页。2.一维数组元素引用的程序实例#include void main() int i,a10; for (i=0; i=0; i-) printf(%d ,ai); printf(n); 运行结果如下:9 8 7 6 5 4 3 2 1 0 说明:1、第一个for循环的作用是给a数组

45、中的元素赋值。2、第2个for循环的作用是所按逆序输出a数组中的10个元素编写程序第73页,共139页。对数组元素初始化的实现方法: 1.在定义数组时对数组元素赋以初值。例如:int a10=0,1,2,3,4,5,6,7,8,9;将数组元素的初值依次放在一对花括弧内。经过上面的定义和初始化之后,a0=0,a1=1,a2=2,a3=3,a4=4,a5=5,a6=6,a7=7,a8=8,a9=9。 6.2 一维数组的定义和引用6.2.3 一维数组的初始化第74页,共139页。 3. 如果想使一个数组中全部元素值为0,可以写成: int a10=0,0,0,0,0,0,0,0,0,0; 或 int

46、 a10=0; 2. 可以只给一部分元素赋值。例如: int a10=0,1,2,3,4; 定义a数组有10个元素,但花括弧内只提供5个初值,这表示只给前面5个元素赋初值,后5个元素值为0。第75页,共139页。4. 在对全部数组元素赋初值时,由于数据的个数已经确定,因此可以不指定数组长度。 例如:int a5=1,2,3,4,5; 也可以写成 int a=1,2,3,4,5; int a10=1,2,3,4,5; 只初始化前5个元素,后5个元素为0。第76页,共139页。Fibonacci数列公式:已知: a1=a2=1,an=an-1+an-2 即:1,1,2,3,5,8,13建立一个数组

47、,将数列中第1个数放在数组第1个的元素中,数列第2个数放在数组第2个的元素中,。 6.2 一维数组的定义和引用6.2.4 一维数组程序举例例题 6.2 用数组来处理求Fibonacci数列问题。 解题思路第77页,共139页。程序实例:#include void main() int i; int f20=1,1;6.2 一维数组的定义和引用6.2.4 一维数组程序举例编写程序第78页,共139页。for(i=2;i20;i+)fi=fi-2+fi-1;for(i=0;i20;i+) if(i%5=0) printf(n); printf(%12d,fi) /*For循环结束*/ /*程序结束

48、*/运行结果如下: 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765if语句用来控制换行,每行输出5个数据。第79页,共139页。例题 6.3 假如有n个人,各人年龄不同,希望按年龄将他们从小到大排列。 解题思路 这种问题称为数的排序(sort)。排序的原则有两 类,一类是“升序”,从小到大;一类是“降序”,从大到小。我们可以把这个题目抽象为一般形式: 对n个数按升序排列 对一组数据进行排序的方法很多,本例介绍用“起泡法”排序。“起泡法”的思路是如下第80页,共139页。第一趟比较 经过第一趟(共5次比较与交换

49、)后,最大的数9已“沉底” 。然后进行对余下的前面5个数第二趟比较,第81页,共139页。第二趟比较如果有n个数,则要进行n-1趟比较。在第1趟比较中要进行n-1次两两比较,在第j趟比较中要进行n-j次两两比较。第82页,共139页。程序流程图如下:第83页,共139页。#include void main() int a10; int i,j,t; printf(input 10 numbers :n); for (i=0;i10;i+) scanf(%d,&ai); printf(n); 编写程序第84页,共139页。for(j=0;j9;j+) for(i=0;iai+1) t=ai;a

50、i=ai+1; ai+1=t; printf(the sorted numbers :n); for(i=0;i10;i+) printf(%d ,ai); printf(n);/*程序结束*/程序运行结果如下:input 10 numbers:1 0 4 8 12 65 -76 100 -45 123the sorted numbers:-76 -45 0 1 4 8 12 65 100 123说明:1、程序中实现起泡法排序算法的主要是1013行。 2、仔细分析嵌套的for语句。 第85页,共139页。 6.3 二维数组的定义和引用 6.3.1 定义二维数组二维数组定义的一般形式为类型说明符

51、 数组名常量表达式常量表达式;例如:定义a为34(3行4列)的数组,b为510(5行10列)的数组。如下:float a34,b510;不能写成 float a3,4,b5,10;第86页,共139页。C语言中,二维数组中元素排列的顺序是按行存放的,即在内存中先顺序存放第一行的元素,再存放第二行的元素。下图表示对a34数组存放的顺序。 a00 a01 a02 a03 a10 a11 a12 a13 a20 a21 a22 a23 6.3 二维数组的定义和引用 6.3.1 定义二维数组第87页,共139页。二维数组元素的表示形式为:数组名下标下标例如: a23下标可以是整型表达式,如 a2-12

52、*2-1数组元素可以出现在表达式中,也可以被赋值例如:b12=a23/2不要写成 a2,3,a2-1,2*2-1形式6.3 二维数组的定义和引用6.3.2 引用二维数组的元素第88页,共139页。常出现的错误有: int a34; /* 定义a为34的数组 */ a34=3; 在使用数组元素时,应该注意下标值应在已定义的数组大小的范围内。6.3 二维数组的定义和引用6.3.2 引用二维数组的元素第89页,共139页。可以用下面4种方法对二维数组初始化:.分行给二维数组赋初值。例如: int a34=1,2,3,4,5,6,7,8,9,10,11,12; .可以将所有数据写在一个花括弧内,按数组

53、排列的顺序对各元素赋初值。例如:int a34=1,2,3,4,5,6,7,8,9,10,11,12; 6.3 二维数组的定义和引用 6.3.3 二维数组的初始化第90页,共139页。.可以对部分元素赋初值。例如: int a34=1,5,9; 1 0 0 05 0 0 0 9 0 0 0也可以对各行中的某一元素赋初值,如int a34=1,0,6,0,0,11; 1 0 0 00 6 0 00 0 0 11 1 0 0 05 6 0 0 0 0 0 0也可以只对某几行元素赋初值。如:int a34=1,5,6; 第91页,共139页。.如果对全部元素都赋初值,则定义数组时对第一维的长度可以不

54、指定,但第二维的长度不能省。例如:int a34=1,2,3,4,5,6,7,8,9,10,11,12;它等价于:int a4=1,2,3,4,5,6,7,8,9,10,11,12;在定义时也可以只对部分元素赋初值而省略第一维的长度,但应分行赋初值。例如:int a4=0,0,3,0,10;0 0 3 00 0 0 00 10 0 0第92页,共139页。 6.3 二维数组的定义和引用 6.3.4 二维数组程序举例例如:a= 1 2 3 1 4 4 5 6 b= 2 5 3 6例题 6.4 将一个二维数组a的行和列的元素互换(即行列转置),存到另一个二维数组b中。 解题思路 将a数组中第i行j

55、列元素赋给b数组中j行i列元素,例如a00赋给b00,a01 赋给b10,a02赋给b20,。可以用双层循环来处理,用外循环控制行的变化,内循环控制列的变化。第93页,共139页。 6.3 二维数组的定义和引用 6.3.4 二维数组程序举例#include void main() int a23=1,2,3,4,5,6; int b32,i,j; printf(array a:n); for (i=0;i=1;i+) for (j=0;j=2;j+) 编写程序第94页,共139页。 printf(%5d,aij); bji=aij; printf(n); printf(array b:n);f

56、or (i=0;i=2;i+) for(j=0;j=1;j+) printf(%5d,bij); printf(n); /*程序结束*/运行结果如下:array a: 1 2 3 4 5 6array b: 1 4 2 5 3 6 说明:如果把第7行:“for (i=0;i2;i+)”改为“for (i=0;i=2;i+)”,意味着什么?结果会怎样?第95页,共139页。例题 6.5 有一个班30个学生,己知每个学生有5门课的成绩,要求输出平均成绩最高的学生的成绩以及该学生的序号。 解题思路 对本题而言,宜用二维数组,用一行中的各元素存放一个学生的成绩,即行代表学生,列代表一门课的成绩。要存放

57、30个学生5门课的成绩,要用一个30*5的二维数组。另外,由于要比较各人的平均成绩,因此,对每个学生来说,应该存放6个数据,每人平均成绩要计算出来,并存放在数组中。这样,数组的大小就应该是30*6。设计算法:(1)求每人平均成绩,放在数组每一行的最后一列中;(2)找出最高的平均分,和该学生的序号;(3)输出最高的平均分,和该学生的序号。第96页,共139页。程序如下: #include void main() int i,j,max_i; float sum,max=0; float s66=78,82,93,74,65,91,82,72,76,67,100,90,85,72,98, 67,8

58、9,90,65,78,77,88,99,45,89,78,89,76,99.97; for (i=0;i5;i+) sum=0; /* 使sum初值为0 */ for (j=0;j5;j+) sum=sum+sij; /* 累加序号为j的学生各门课的成绩 * si5=sum/5; /* 求序号为j的学生各门课的的平均分 */ 编写程序第97页,共139页。for (i=0;imax) /* 逐个将5个学生的平均分与max比较 */ max=si5;max_i=i; /* 如果比max大,就用序号为i的学生的平均分取代max的原值,将i的当前值保存在max_I中 */ printf(stu_or

59、der=%dnmax=%7.2fn,max_i,max); /* 输出最高平均分和该生的序号i */ 运行结果如下:max=10,row=2,colum=1 说明: 1、在对数组初始化时,只对各行的前5列赋初值,第6列默认为0。2、注意第一个for语句的范围。请思考能否不要“sum=0;”这一行?或者把这一句改放到for语句的前面? 3、第三个for语句内嵌了一个if语句,用来将5个学生的平均分逐个与max比较 第98页,共139页。6.4 字符数组6.4.1 定义字符数组及对其初始化定义方法与前面介绍的类似。例如:char c10;c0=I;c1= ;c2=a;c3=m;c4= ;c5=h;

60、c6=a;c7=p;c8=p;c9=y;第99页,共139页。对字符数组初始化,可逐个字符赋给数组中各元素。例如:char c10=I,a,m,h,a,p,p,y 6.4 字符数组6.4.1 定义字符数组及对其初始化第100页,共139页。如果初值个数小于数组长度,则只将这些字符赋给数组中前面那些元素,其余的元素自动定为空字符。char c10=c, ,p,r,o,g,r,a,m; 第101页,共139页。如果提供的初值个数与预定的数组长度相同,在定义时可以省略数组长度,系统会自动根据初值个数确定数组长度。char c=I, ,a,m, ,h,a,p,p,y;数组c的长度自动定为10。 第10

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论