版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第六章 循环结构程序设计本章学习目标:l 掌握while语句及其应用l 掌握for语句及其应用l 掌握do-while语句及其应用l 掌握break、continue语句及其应用61 从求和说起图6-1 求和计算流程图YNsum0i1i100?sumsum+tii+1输出 sumti在一个数据集中找出满足特定条件的数据、方程求根、数据排序、定积分计算等许多典型的数据处理功能的实现中大都需要循环结构,没有循环结构,我们几乎不能使用计算机解决任何复杂的问题,可见循环结构程序的重要性。本节讨论什么是循环结构以及为什么需要循环结构,其他章节讨论C语言循环结构的表示方法以及如何应用循环结构解决实际问题。
2、循环的概念很简单:一个操作被重复执行若干次就是循环。引入循环的原因同样简单,就是因为解决实际问题的需要。仔细观察一下我们的日常工作,大多与循环有一定的联系,学生每天重复的事情是上课;会计每天重复的事情是记账;医生每天重复的事情是治病;总之我们日常从事的工作许多都是重复,实际上就是循环,这里的重复不是机械地重复。让我们从一个简单的问题说起,如果我们需要计算s=1+2+3+100,最简单的方式就是利用公式计算出结果,现在我们对这个问题加一点限制,首先不允许使用计算公式,然后给你一个大箱子和一大堆小球,请你利用这些道具完成上述计算,你会如何算出1+2+3+100的结果呢?我们可以这样进行,首先将箱子
3、倒空,然后依次取1个球投进箱子、取2个球投进箱子、取3个球投进箱子,如此进行下去,直到取100个球投进箱子,这时箱子里球的数量就是前100个数的累加和。这一过程可以表示成如下算法:S1: sum0S2: 让i从1变到100,每次加1,重复执行S3、S4S3: tiS4: sumsum+iS5: 输出sum图6-1就是该算法的流程图表示形式。在上述算法中,“ti,sumsum+t,ii+1”操作是一个需要被重复执行的操作,当i=1时执行一次、当i=2时执行一次、当i=3时执行一次、当i=4时执行一次、当i=100时执行一次,该操作一共被执行了100次,被重复执行的操作成为循环体。根据算法我们可以
4、写出计算机程序,然后再计算机上运行程序从而获得问题的解。对于上述问题求解方式读者可能会存在这样的一些疑问:(1)为什么不直接使用计算公式n*(n+1)/2直接算出计算结果?(2)算法6-1中的操作“ti”是不是多余的操作,为什么不使用“sumsum+i”直接将i的数值累加到sum中呢? 第一个问题的回答是这样的,这里我们是试图使用简单问题来说明一种问题求解思路,而不是说这个问题必须使用这样的方式求解,如果使用更加复杂的问题来说明这种问题求解方法,并不能对阐述问题求解方法带来任何帮助,相反可能不利于理解。关于第二个问题,算法中的操作“ti,sumsum+i”在实际使用时完全可以合并成“sumsu
5、m+i”,那么我们为什么要多此一举呢?这是因为我们希望把这个算法当做一个更加普遍的问题求解算法的基础,看一下这样做的好处吧,如果把:“ti”修改为:“t2i”,那么算法将实现计算sum=2+4+198+200,如果把:“ti”修改为:“t2i-1”,那么算法将实现计算sum=1+3+197+199,如果把:“ti”修改为:“tf(i)”,那么算法将实现计算sum=f(1)+f(2)+f(3)+f(199)+f(200),这里f(i)表示利用i计算出一个函数值,这就是为什么在算法中使用了一个看起来“多余”的操作的原因。这个求和的问题是计算机程序设计的一个及其重要的问题,图6-1表示的问题求解算法
6、可以看做是一个可以看做是一个累加和问题求解的“求和原型算法”,怎么样理解这个“原型算法”呢?让我们来看几个世纪应用中经常遇到的一些问题:1)平均值的计算:2)标准差计算:3)级数计算:4)定积分计算:上述问题的共同特点是什么?那就是它们都是求和,如果使用算法求解这些问题,都可以将图6-1表示的算法通过简单的变化而获得相应问题的求解算法,从算法角度看,它们的差别就是t的计算方法不同,因此读者务必要将图6-1所表示的算法给予足够的理解,真正理解了这个算法之后,对于很多问题的求解将是非常有帮助的,这就是为什么把这个算法称为“原型算法”的原因,这也是我们为什么强调这个求和算法原因,对于上述的几个问题的
7、具体求解算法将在本章的后续部分将予以介绍。有了算法之后,接下来就是使用计算机语言书写程序,因为算法中存在着重复操作,因此需要有表达这种重复操作的C语言语句,C语言提供了三种表达循环结构的循环语句,这三种语句是while循环语句、for循环语句和do-while循环语句,分别用于表达不同的循环结构。62 C语言循环结构6.2.1. while循环在2.3节中我们引进了当型循环,在C语言中,当型循环也叫while循环,是一种非常常见的循环方式,这种循环的基本结构及其C语言的表示如图6-2所示:NY图6-2 当型循环结构OPexpr?图6-2的伪代码形式也已表示成: While expr do OP
8、 End while图6-2对应的C语言形式是: while(expr) OP;中文含义是:当expr满足时,重复做 OP操作这里expr表示条件,条件可以是:l 关系表达式l 逻辑表达式l 算术表达式表达式的真假含义与判断结构中条件的含义相同,再次提醒读者注意的一点是当条件为一算术表达式时,如果算术表达式的计算结果不是0则表示为真,如果算术表达式的计算结果为0则表示为假,图6-1中的流程图清楚地表达了循环的含义,只要条件C满足(计算结构为真),则执行OP操作,执行完OP操作后再次判断条件是否满足,只要条件满足就继续执行OP操作,因此OP操作可能被重复执行若干次,循环语句结束的条件是条件C计算
9、结果为假,循环体OP 可以是:l C语言语句或函数l 复合语句l 另一循环语句(见复杂循环结构)l 空语句初学者常常会把“while( expr ) OP;”和“while( expr ) ; OP;”混淆,前者的循环体为OP,后者的循环体为空语句,OP不是while语句的循环体。/*一个简单的while循环程序*/#include stdio.hmain()int i; i=1; while(i=10) printf(%dn,i); i+;黑体字表示的是循环语句,本章的程序中的黑体字均表示循环语句,程序的输出结果是:12345678910对于上述程序,请读者回答如下问题:1) 循环语句结束后
10、,变量i的数值是多少?2) while语句的循环体是什么?3) 如果“i+”改为“i=i+2”,程序的输出结果是什么?4) 如果“printf(%dn,i); i+;”改为“i+;printf(%dn,i);”,程序的输出结果是什么?再看下面的类似的程序:#include stdio.hmain()int i; i=1; while(i+=10) printf(%dn,i);程序的输出结果是:234567891011为什么第一个输出结果是2而最后一个输出结果是11呢?原因是当i=1时,i+=10计算结果为真,但完成次计算后变量i的值已经变为2了,因此输出第一个数据为2,同样的道理当i的值为10
11、时,i+=10计算结果为真,完成计算后i的值变为11了,所以输出结果为11.,当i的值为11时,i+=10计算结果为假,循环语句结束,但完成计算后i的值变为12了,所以整个循环语句结束后,变量i的值是12。6.2.2 for循环图6-3 常见的循环形式NYexpr1expr2?OPexpr3在存在循环结构的问题求解算法中,普遍存在图6-3所示的结构。为此人们设计了专门用于描述这种循环结构的C语言语句,这就是for循环语句。图6-8对应的C语言循环语句的格式是:for(expr1;expr2;expr3) OP;其中expr1、expr2和expr3为三个C语言表达式,OP为C语言语句。图6-3
12、清楚地描述了这个循环语句的执行过程,用自然语言描述的for语句的执行过程是:S1:计算expr1S2:计算expr2,如果结果非0(为真),则转向S3,否则结束循环语句S3:执行OPS4:计算expr3S5:转向S2显然这个过程也可以使用while语句表示,图6-3的while语句表达形式如下:expr1;while(expr2) OP; expr3;for语句具有很强的表达能力,使用for需要注意:(1) expr1和expr2通常是赋值表达式,使用其他的计算表达式一般没有意义,expr2通常是循环控制表达式,表示循环进行的条件,条件不满足(为假)则for语句执行结束。(2) expr1、e
13、xpr2和expr3三个表达式均可以省略,需要注意的是如果expr2省略,则表示expr2永远为真,如果循环体OP中没有结束循环的控制,将形成死循环。(3) 语句OP可以是基本的C语言语句,也可以使复合语句,甚至是另一循环语句。一种典型的for语句的用法是:for(i=1;in;i+) S;其执行过程是当i=1时,执行一次S;i=2时,执行一次S;i=3时,执行一次S;i=n时,执行一次S;i=n+1时,for循环语句结束,整个循环语句中S共执行了n次。这个循环语句也可以这样理解:让i从1变到n每次加1,重复执行S。6.2.3 do-while循环do-while循环结构也是常用的一种循环表达
14、形式,其流程图形式如图6-41所示。对应的C语言表达形式如下:对应的C语言表示图6-4 do-while循环结构示意图doOP;while(expr);NYOPexpr?Do-while循环的伪代码形式可表示为与C语言类似的形式: Do OP While expr这里expr表示循环控制条件,它可以是任何C语言表达式,当expr为一算术表达式时,计算结果非0表示真,为0表示假,OP表示循环体,循环体可以是C语言的语句或者符合语句,也可以是另一循环语句,do-while语句的执行过程是:(1)执行循环体OP(2)计算表达式expr(3)如果表达式expr为真,则转向(1),否则结束循环语句由于是
15、限制性循环体后进行判断,因此,在do-while循环中,循环体OP至少被执行一次,而while循环是先判断后执行循环体,所以while循环的循环体OP最少被执行0次,假设s和i都是整数,对比下面两个程序段:s=0; s=0;i=15; i=15;while(i=10) do i+; i+; s=s+i; s=s+i; while(i=10); 左边的程序段循环语句(while语句)循环结束后,变量s的值是0,而右边的程序段循环语句结束后,变量s的值是16。6.2.4 三种循环结构之间的关系C语言可以使用三种不同的循环语句来表达循环,不同的结构可根据需要选择适当的循环语句来表示,但每种循环语句都
16、可以用其他的循环语句替代,他们之间是可以相互转换的。例如对于while语句,可以用另外两种语句表示。例如while循环语句:while(expr) OP;可表示为:for( ;expr; ) OP;或者if(expr) Do OP; while(expr);同样对于for语句:for(exp1;exp2;exp3) OP;可以表示为:exp1;while(exp2) OP;exp3;或者exp1;if(exp2) do OP;exp3; While(exp2);对于do-while语句,同样可以用另外两种表达形式来表示,总之任何一种循环语句,可以使用另外两种循环语句表示。从逻辑上说,只需要一种
17、表达形式就够用了,但实际使用时,不同的结构都有比较适合的表达形式,应选择容易理解的表达形式。图6-5 计算1+2+3+99+100算法YNi1结束i100?ss+iii+1输出ss0例6-1 计算并输出1+2+3+100。图6-5表示了累加计算的基本流程,6.1节我们强调了这个算法的重要性,现在的任务是将该算法使用C语言表示出来,构成一个C语言程序。使用for语句实现循环是最为简单明了的一种表达形式,for循环语句的格式是:for(expr1;expr2;expr3) OP;对比for循环结构示意图6-3,可以看出:expr1对应着“i1”expr2对应着“i100”expr3对应着“ii+1
18、”OP对应着“ss+i”基于for循环实现的C语言程序如下:#include main()int s,i;s=0; for(i=1;i=100;i+) s=s+i; printf(%dn,sum);上述表达形式是最自然的一种表达形式,其含义是:当i=1时,执行s=s+i,当i=2时,执行s=s+i,当i=3时,执行s=s+i,当i=100时,执行s=s+i,从而使得变量s中最后存储的是前100个数的和。如果使用while循环表示上述循环结构,则循环控制条件expr为“i100”,循环体OP为“ss+i;ii+1”,基于while循环实现的C语言程序如下:#include stdio.hmain
19、()int i;s; s=0;i=1; while(i=100) s=s+i; i+; printf(%dn,s);程序的输出结果是:5050仔细分析上述程序,请读者回答如下问题:2) 如果将“i=100”改为:“i=200”,程序的运行结果是什么?3) 如果将“s=0;i=1;”改为:“s=0,i=0;”,程序是否正确?4) 如果将“i=1”改为:“i=2”,程序的运行结果是什么?5) 如果将“i+”改为:“i=i+2”,程序的运行结果是什么?6) 如果将“s=0;i=1”改为:“i=1”,程序的运行结果是什么?7) 如果要计算1+2+3+10000,程序改如何修改?基本的累加和算法是一个极
20、为重要的算法,许多问题的求解算法都可以通过这个算法的简单变化得到。我们看一些简单的变化情况:1) 计算1+1/2+1/3+1/99+1/100,只需将算法中的“ss+i”改为“ss+1/i”2) 计算1+1/(2*2)+1/(3*3)+1/(99*99)+1/(100*100),只需将算法中的“ss+i”改为“ss+1/(i*i)”3) 计算1+3+5+97+99,只需将算法中的“ii+1”改为“ii+2”4) 计算1/(1*2)+1/(2*3)+1/(99*100)+1/(100*101),只需将算法中的“ss+i”改为“ss+1/i/(i+1)”也可以使用do-while循环语句书写,程序
21、如下:/*do-while循环实现的累加*/#include stdio.hmain()int sum,i; sum=0; i=1; do sum+=i; i+; while(i=100); printf(%dn,sum);6.2.5 死循环当循环条件永远为真时,循环语句将永远不能结束,我们把这种情况成为死循环。死循环常常是我们需要避免的,由于C语言不进行数据越界处理,不小心就会形成死循环,很多情况可能造成循环条件永远满足,几种常见的情况是:(1)循环条件为常数,而循环体中没有结束循环的语句(见循环控制),例如:int x=0;while(1)x+;(2)程序书写格式出现错误导致的死循环,例如
22、:s=0;i=1;while(i100); s+=i;i+;这个循环语句的循环体为一个空语句,因此变量i的值将永远为1,不可能结束循环。(3)使用不可能达到的数值作为循环控制条件,例如:char ch=65;while(chmax then maxx End ifEnd forPrint max基于上述算法编写的C语言程序如下:#include main()int x,max,i; scanf(%d,&x); max=x; for(i=2;imax) max=x; printf(max=%dn,max); getchar();getchar();运行程序输入:23 56 19 527 768
23、453 123 90 26 11程序输出:max=768问题:(1)如果需要输出第几个输入的数是最大数,程序如何修改?(2)如果需要同时计算出最大数和最小数,程序改如何修改?例6-3 输入两个正整数m和n,求m和n的最大公约数。YN输入m、n开始inii-1m、n同时除尽i?输出i结束图6-6 计算m、n的最大公约数求解这个问题通常有两种方法,一是根据最大公约数的定义设计算法求解问题,二是采用著名的最大公约数算法-辗转相除法。图6-6给出了基于最大公约数定义的求解算法,在例2-7中我们假设m=n,主要是为了便于理解,实际上这一假设可以取消。图6-6算法的伪代码形式是:Input m,ninWh
24、ile m mod i0 or n mod i0 do i-i-1End whilePrint i实现该算法的C语言程序如下:#include stdio.hmain()int m,n,i; scanf(%d%d,&m,&n); i=n; while(m%i!=0 | n%i!=0) i-; printf(%dn,i);运行程序,当输入35 42时,程序输出结果是:7注意循环结束的条件是出现m和n能同时除尽的i,由于i是从大向小变的,所以这时的i就是最大公约数。另外一种方法是让i从小向大变化,将m和n能同时除尽的i记录下来,那么最后一次被记录下的i的值就是最大公约数,根据这一思路编写的程序如下
25、,请读者仔细对比两者的差异在这个程序中,增加了一个变量r,用于记录m和n能同时除尽的i,因为变量i是从小向大变化的,因此最后记录在r中的数就是最大公约数。#include stdio.hmain()int m,n,i,r; scanf(%d%d,&m,&n); i=1; while(i=n,函数gcd(m,n)表示m和n的最大公约数,令c=gcd(m,n),即m=k1*c,n=k2*c,m=k*n+r,r是m除以n的余数,显然如果r=0的话,那么m和n的最大公约数必为n,如果r不为0,那么:m=k*n+r k1*c=k*k2*c+r r=(k1-k*k2)*c,即c也必然是n和r的一个公约数,
26、而c1=gcd(n,r)是n和r的最大公约数,所以:c1=c=gcd(m,n)同理如果c1=gcd(n,r),必有n=k3*c1,r=k4*c1,因为m=k*n+r,所以:m=k*n+r=k*k3*c1+k4*c1=(k*k3+k4)*c1即c1必然是m和n的公约数,而c是m和n的最大公约数,所以c1=c 因此c1=c,即gcd(m,n)=gcd(n,r)。辗转相除法算法正是基于这样的原理来设计的,流程图表示的算法如图6-7所示。图6-7 基于辗转相处法的最大公约数算法YN输入m、n开始im mod nmn,nrr=0?输出n结束im mod n基于辗转相除法的最大公约数计算方法的伪代码表示的
27、算法如下:Input m,nrm mod nWhile r0 do mn nr rm mod nEnd whilePrint n对应的C语言程序如下:#include stdio.hmain()int m,n,r; scanf(%d%d,&m,&n); r=m%n; while(r!=0) m=n;n=r; r=m%n; printf(%dn,n);运行程序,输入26 65 时,程序的输出是:13需要说明的一点是关于这个算法的许多资料的描述时,对于mn时都进行数据交换,实际上这是不必要的,下面是取自其他有关书籍中的辗转相除法程序,读者体会其中的差异。#include stdio.hmain()
28、int m,n,r,t; scanf(%d%d,&m,&n); if(m2),只需要让n依次除以2、3、.、n-1,如果n能除尽其中的某一个或者几个的话,那么n必然不是素数,否则的话,n就是素数。我们可以使用一个变量(比如flag)来表示n 是否能被某个数除尽,flag=0表示n能除尽某个数,即n不是素数,flag=1表示n不能除尽2、3、.、n-1中的每一个数,即n是素数。实现素数判断的算法如图6-8所示。NYNYYN输入n开始结束flag1,i2in?n mod i=0?flag0ii+1flag=1?输出prime输出not prime图6-8 判断n是否为素数算法算法的伪代码形式如下:
29、Input nFlag1,i2While in do If n mod i=0 then Flag0 End if ii+1End whileIf Flag=1 then Print “prime”Else Print “not prime”End if基于上述算法编写的C语言程序如下:#include stdio.hmain()int n,flag,i;scanf(%d,&n);flag=1;i=2;while(in)if(n%i=0)flag=0;i+;if(flag=1)printf(primen);elseprintf(not primen);运行程序,输入31时程序输出prime输入
30、39时程序输出:not prime-请读者回答如下问题:1)“if(flag=1”是否可以改为“if(flag)”?为什么?2)如果将程序的“flag=1”改为“flag=3”,程序还需要修改哪里?3)如果程序要求输出是“31 is a prime”、“39 is a not prime”这样的形式,输出函数需要进行怎样的修改?关于算法的改进:程序的循环变量i是从2变到n-1,这样循环体被执行了n-2次,实际上变量i只需要从2变到sqrt(n)就够了,因为如果n=a*b的话,那么a和b中至少有一个小于sqrt(n),因此i从2变到sqrt(n)就足够了。改进后的程序如下:-#include s
31、tdio.h#include “math.h”main()int n,flag,i;scanf(%d,&n);flag=1;i=2;while(i=sqrt(n)if(n%i=0)flag=0;i+;if(flag=1)printf(primen);elseprintf(not primen);-还有什么可以改进的吗?实际上执行循环语句时需要进行n-1次判断i=sqrt(n),每次判断都需要计算sqrt(n),实际上可以在循环之前将sqrt(n)的值保存到变量m中,循环中使用while(i=m)就行了,这样执行效率更高些,读者可以自行完成这种改进,更进一步实际上不需要调用函数sqrt(n)也可
32、以实现循环次数不超过sqrt(n)次。64 循环结构应用641 求和与循环求和是一类和普遍的问题,我们通过几个具体问题来了解这类问题的求解方法。1 计算平均值图6-9 平均值计算流程图YNsum0i1i10?sumsum+xii+1输出 avgavgsum/10输出 x问题: 从键盘输入10个数,求出这10个数的平均值,平均值就是累加和除以数据个数:这个问题的求解算法可以通过图6-1的算法的一个简单的变化得到,使用x表示输入的数据,使用avg表示数据平均值,图6-9表示了计算平均值的算法,黑体字部分是对算法6-1的修改地方。基于上述算法编写的C语言程序如下:#include main()flo
33、at x,sum,avg; int i; sum=0; for(i=1;i=10;i+) scanf(%f,&x); sum=sum+x; avg=sum/10; printf(average=%fn,avg);运行程序输入:1 2 3 4 5 6 7 8 9 10程序输出:average=5.500000使用while循环语句表达的程序如下:#include main()float x,sum,avg; int i; sum=0; i=1; while(i=10) scanf(%f,&x); sum=sum+x; i+; avg=sum/10; printf(average=%fn,avg)
34、;请回答如下问题:如果上述程序的for语句:for(i=1;i1e-6?ee+tnn+1tt/n输出e结束图6-10 计算自然数的流程图计算自然数e的值,计算进行到最后一项数据为止。实际上这也是一个求和的问题,参与累加的数据中包含了阶乘数据,阶乘计算本身又需要循环,怎样方便地计算车每项的阶乘数据呢?实际上k!=(k-1)!*k,而(k-1)!又刚好是上一次计算的阶乘,所以只要利用上次结成计算的结果就可以算出下次阶乘。这样可以避免多次的循环,自然运行效率会更高,阶乘的倒数计算方法类似。流程图表示的算法如图6-10所示,这个算法也是求和算法的简单变换得到的。这里t表示每次需要累加的数据项,即阶乘的
35、倒数,当n=k时,t存储的是1/(k!),当n=k+1时,利用tt/n计算出新的值,这时t=t/n=(1/(k!)/(k+1)=1/(k+1)!),刚好是需要累加的数据项,显然数据e和t是实数数据。完整的C语言程序如下:#include stdio.hmain()int n; float e,t; e=1.0;t=1.0;for(n=1;t1e-6;t=t/n) e=e+t; n+; printf(%fn,e);程序的输出结果是:2.718282上述程序使用while循环表示更加容易理解,基于while循环编写的C语言程序如下:#include stdio.hmain()int n; floa
36、t e,t; e=1.0;t=1.0; n=1; while(t1e-6) e=e+t; n+; t=t/n; printf(%fn,e);级数计算是一个非常典型的累加和计算问题,任何函数度可以表示成一个级数的形式,实际上就是一个多项式的累加和,没有学过级数的读者只要把级数当做一个累加和问题就可以了,不影响理解。对于累加和问题,可以采用如下算法:S0i1ta1While c(t)=true do SS+t ii+1 t计算End whilePrint S这里c(t)表示循环结束条件,c(t)=true表示满足循环条件,执行循环体,c(t)=false表示不满足循环条件,循环结束,需要注意的是常
37、常可以由算出,例如对于下面的函数:我们的任务是设计一个程序,对任意输入的x,计算出函数f(x)的值,当时停止累加计算,设s表示累加和,t表示每一项数据,可以设计这样的算法:Input xs0;i0t1While t1e-6 do ss+t /*将数据项累加到s中*/ i1e-6) s=s+t; i+; t=t*x/i; printf(%fn,s);运行程序输入1时,程序输出结果是:2.718282上述程序当x=1时,就是计算自然数e,程序结构书基本一致。3 的近似计算问题: 利用公式计算的近似值,直到最后一项数据的绝对值小于。YNsum0 , sign1开始结束t1.0 , n1psign*t
38、sumsum+tnn+2sign -signt1.0/nt1e-6?输出sum图6-11计算的流程图求解分析:这是累加和的计算问题,参与累加的每项数据可以通过如下数据获得:n: 1 3 5 7 t=1/n: 1 1/3 1/5 1/7 sign: +1 -1 +1 -1 p=sign*t: 1 -1/3 1/5 -1/7 图6-11表示了计算的流程图算法,这个循环是典型的do-while循环结构,因此使用do-while循环语句表示图6-11算法中的循环结构时最为自然的,基于图6-11所示的算法编写的C语言程序如下:#include stdio.hmain()float sum,t,p; in
39、t n,sign; sum=0; sign=1; t=1.0; n=1; do p=sign*t; sum=sum+p; n=n+2; /*循环体*/ sign=-sign; t=1.0/n; while(t1e-6);printf(%fn,4*sum);程序的输出结果是:3.1415944 定积分计算根据定积分定义,函数f(x)在区间a,b上的积分定义为:图6-12给出了定积分的示意图:其中h=(b-a)/n,当时,s就是定积分的值,定积分的计算需要求原函数,如果求不出原函数,我们常常使用近似方法来计算定积分的近似值,即设定一个足够大的n,使用上面的公式来计算定积分的近似值。实际上定积分被看
40、做n个小矩形面积之和s=s1+s2+s3+sn,其中s1=h*f(a)、s2=h*f(a+h)、sn=h*f(a+(n-1)*h),定积分的近似有若干种方法,这里我们讨论两种:l 矩形法:将每个小面积近似看做一个矩形l 梯形法:将每个小面积近似看做一个梯形baxyf(x) 图6-12 定积分计算示意图对于定积分的近似计算,理论上说n越大,计算结果越准确,因为n趋于无穷大时就是定积分的精确值。定积分近似计算也是求和,因此也可以通过图6-1表示的算法的简单变换得到,基于矩形法的算法表示为:Input a,b,ns0h(b-a)/nFor i=0 to n-1 step 1 do fxf(a+i*h
41、) ss+h*fxend forprint s例6-5 用矩形法近似计算函数f(x)=x*x在0,3上的定积分。基于上述算法编写的程序如下:#include stdio.hmain()float a,b,h,s,fx; int i,n; scanf(%f%f%dn,&a,&b,&n); s=0; h=(b-a)/n; for(i=0;in;i+) fx=(a+i*h)*(a+i*h); /*计算f(a+i*h)的值*/ s=s+h*fx; printf(s=%fn,s);运行程序当输入0 3 1000时,程序输出:s=8.986502-实际上定积分的精确值是3.0。表6-1给出了不同的n的值与
42、计算精度的关系: 表6-1- n a b s 1000 0 3 8.986502 2000 0 3 8.993247 3000 0 3 8.995502 4000 0 3 8.996632 5000 0 3 8.997301 6000 0 3 8.997753 7000 0 3 8.998065 8000 0 3 8.998319 9000 0 3 8.998504 10000 0 3 8.998650可以看出,随着n的增大,计算结果更加逼近于定积分的实际值(9.0)。使用矩形法计算定积分的近似值时,由于使用小矩形近似代替小区间的积分面积,所以产生误差就比较大,每个小面积使用一个梯形面积来近似
43、表示似乎是个更加精确地方法,梯形面积比矩形面积更加接近于实际面积。基于梯形法的定积分计算算法描述如下:Input a,b,ns0h(b-a)/nFor i=0 to n-1 step 1 do fx1f(a+i*h) fx2f(a+(i+1)*h) ss+(fx1+fx2)*h/2 /* (fx1 + fx2) *h /2*/end for /*(上底+下底)*高/2*/print s例6-6 用梯形法近似计算函数f(x)=x*x在0,3上的定积分。#include stdio.hmain()float a,b,h,s,fx1,fx2; int i,n; scanf(%f%f%dn,&a,&b
44、,&n);s=0; h=(b-a)/n; for(i=0;in;i+) fx1=(a+i*h)*(a+i*h); fx2=(a+(i+1)*h)*(a+(i+1)*h); s=s+(fx1+fx2)*h/2; printf(s=%fn,s);运行程序当输入0 3 1000时,程序输出:s=9.000003显然梯形法比矩形法计算的精度更加精确(接近9.0)。642 穷举与循环一类非常普遍的问题是在一个给定的有限数据集合S=x1,x2,x3,xn中,找出满足特定条件的所有数据,所谓穷举就是对数据集合中的每个数据元素,判断是否满足给定条件,穷举算法的基本思路是:对于S中的每个数据元素,重复做 如果满足给定条件,则输出例6-7 求出100以内的所有除以7余数为2的数。这个问题非常简单,S=1,2,3,100,求解思路是:对于1100的每一个数n,重复做 如果n mod 7=2 则输出n对应的C语言程序如下:#include main()int n; for(n=1;n=100;n+) if(n%7=2) printf(%dn,n);运行程序会输出所有除7余2的数,请问如果循环体不使用if语句,只使用printf函数输出数据,程
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 护理社区护理学
- 护理纠纷预防的成效评估
- 剖腹产后伤口护理要点
- 护理课件制作工具体验
- 旅游公司市场部经理的招聘要点与技巧
- 零售业门店管理岗位店长面试要点参考
- 快手内容运营面试技巧
- 基于云计算的XX服务解决方案研究报告
- 客户服务代表的心理调适与压力管理
- 即时编译加速引擎在大数据分析中的应用
- 铝电解工(铝电解操作工)职业资格(技师)考试题库-下(多选、判断题)
- 香料基础理论知识单选题100道及答案解析
- 市场营销合同范本
- NB-T10636-2021光伏发电站逆变器及汇流箱技术监督规程
- 列宁人物课件
- 初三三角函数复习教案-
- 社会稳定风险评估业务档案管理制度
- 2016-2023年郑州信息科技职业学院高职单招(英语/数学/语文)笔试历年参考题库含答案解析
- 广西版四年级下册美术教案
- 全国执业兽医考试试题附答案-动物生物化学
- 房建工程监理大纲
评论
0/150
提交评论