《Fortran中的子程序.ppt》由会员分享,可在线阅读,更多相关《Fortran中的子程序.ppt(18页珍藏版)》请在三一办公上搜索。
1、2023/7/6,1,第六讲 Fortran中的子程序,实际中的程序由若干个程序单元组成,但是有且只有一个主程序(Program main),其它的都是子程序。子程序是构造大型实用程序的有效工具,设计程序要善于利用子程序,因此,本讲学习Fortran中的子程序:函数子程序和子例行程序。此外,在Fortran中还有一种类似与函数子程序的语句函数。,1 语句函数,就是用一条语句定义一个函数,比如:,就可以用Fortran的一条语句写出来:,(1)语句函数名:其取名及数据类型与变量相同。,2023/7/6,2,一、语句函数的格式,其中:f 称为函数名,x1、x2、xn称为虚参,e是关于虚参的一个有效
2、表达式。,又比如:Double precision FF FF(x,y)=x*2+y*2定义了一个双精度型函数FF注意在同一程序单元中,语句函数名不能与某个变量同名。,比如:F(x,y)=x*2+y*y定义了一个实型函数FNF(x,y)=x*2+y*y则定义了一个整型函数NF,(3)语句函数表达式给出函数与参数之间的对应关系,可由虚参(必须包含所有的虚参)、常量、变量、数组、Fortran的内部函数及在其前面说明了的语句函数。,2023/7/6,3,(2)语句函数的虚参-即语句函数的自变量,1、称其为“虚参”是因为其本身是没有值的,只有在函数被调用时才用实际意义(叫实参)代替;2、可以按照普通
3、变量对待虚参,但是一个语句函数中虚参不能同名,但不同语句函数中虚参可以同名,虚参也可以和程序中的变量同名;3、虚参的类型说明与变量的类型说明方法与规则相同,而且对与虚参同名变量同时有效;4、当存在多个虚参时,之间用“,”分隔,如果没有虚参则函数名后的括号是不能省略的。,2023/7/6,4,1、只有当函数关系简单到,可以用一条语句描述函数与参数的对应关系时,才能使用语句函数;,2、语句函数是非执行语句,要放在一个程序单元的所有其它说明语句之后,并放在所有可执行语句之前;,3、语句函数只有在本程序单元中才有意义,即不能使用其它程序单元中的语句函数;,此外,还需注意的是:,4、语句函数中的虚参必须
4、是变量,不能是常量、数组元素和内部函数等;,5、语句函数是有类型的,因此语句函数表达式的类型一定要与其函数名同类型。,2023/7/6,5,需要注意下面2个问题:1、调用时可以使用常量、变量、内部函数及其表达式作为实参代替对应的虚参位置,但要保证实参和虚参具有完全相同的类型,并且实参是可以计算值的(即调用前实参中包含的变量全部已经赋值);2、实参和虚参个数相同。比如:,integer x,ff(x)=5*x*3-2*x*2+7*x+6print*,f(-1),f(0),f(1)End运行结果为:8 6 16,2023/7/6,6,一、函数子程序的定义,2023/7/6,7,其中,类型说明用于说
5、明函数名的类型;函数名的命名方法与变量名相同;虚参可以是简单变量和数组变量,但不能是常数、数组元素、表达式。,比如:求,function sm(m,n,l)sm=0do i=m,n if(l0)then sm=sm+i*l else sm=sm+(1.0*i)*l end ifend doendprogram mainwrite(*,*)s1=,sm(1,100,2)write(*,*)s2=,sm(100,140,3)write(*,*)s3=,sm(20,50,-1)end,程序的运行结果为:S1=338350.000000S2=7.291440E+07S3=9.514656E-01,20
6、23/7/6,8,程序说明:1、整个程序由主程序和1个函数子程序组成,二者的位置不分先后,因为程序执行时总是从主程序开始的;2、函数子程序Function SM(m,n,l)中,缺省类型说明时,则函数SM及其虚参标量m、n、l的类型遵守IN规则;3、主程序中的第24语句都要输出SM的值,其调用了函数子程序SM。,2023/7/6,9,2、函数不能有同名虚参。而虚参的类型可以在函数体中说明,没有说明则服从I-N规则;3、在函数体中至少要有一个语句给函数名赋值,这种赋值语句的格式为:函数名表达式切莫在函数名后加入括号,错误地写成:函数名(虚参)表达式。,二、函数子程序的调用,定义函数子程序的目的是
7、为了调用,在Fortran中不仅主程序可以调用函数子程序,而且函数子程序也可调用其它的函数子程序,甚至调用本身(叫递归调用)。常把调用程序叫主调程序单元,而被调用的函数子程序叫被调程序单元。,调用函数子程序的方法与调用内部函数及语句函数基本相同:(1)调用时应该用实参(可以是常量、变量、表达式等)代替函数子程序中的虚参,实参和虚参的类型要相同;,2023/7/6,10,(2)调用程序单元中的变量不能与函数子程序同名。函数值的类型由函数定义程序单元决定,与调用程序单元无关;,(3)当函数名的类型不满足I-N规则时,在调用程序单元中要对函数名的类型给出说明;,(4)不能调用一个没有定义的函数子程序
8、,这一点与内部函数是不同的。,分析:(1)函数子程序susu(n)负责判断n是否为素数,定义为:,2023/7/6,11,(2)主程序调用susu(n),并把素数n输出,以及对素数求和并输出。,!函数子程序function susu(n)integer susususu=0do i=2,n-1 if(mod(n,i)=0)returnend dosusu=1end,!主程序program maininteger susus=0do i=50,100 if(susu(i)=1)then s=s+i write(*,*)i end if end dowrite(*,*)s=,send,2023/7
9、/6,13,注意:(1)子例行程序的命名方法与变量相同。虚参由变量、数组名(不能是数组元素,常数、表达式)充当,当有多个虚参时,之间用“,”分隔,没有虚参时子例行程序名后面的一对括号可以省略;(2)子例行程序的设计方法与函数子程序相同,但不能有对子例行程序名的赋值语句(因为其名字没有值)。,(1)其实参的类型与函数子程序相同,但和函数子程序调用不同的是,子例行程序的调用是一个独立的语句;(2)子例行程序调用的其它事项与函数子程序的调用相同。,2023/7/6,14,(3)子例行程序与调用它的主程序的位置先后顺序也是无关紧要的,因为程序总是先执行主程序;(4)子例行程序和函数子程序在使用上可以相
10、互代替,但是要求子程序有返回值时,宜使用函数子程序;而子程序没有返回值时,最好用子例行程序。,三、子例行程序的例子,问题2:把素数依次从低位去掉1位,2为,所得的各数仍都是素数的数叫超级素数,比如239.试求100,9999内,超级素数的个数、所有超级素数之和、最大的超级素数。【要求用函数子程序】,问题1:用Newtow迭代法求 的一个根。【要求用语句函数】,问题3:亲密数对定义为:正整数AB,但A不含本身的所有因子之和等于B,而B不含自身的所有因子之和等于A,求3000以内所有的亲密数对。【要求用子例行程序】,2023/7/6,15,program newtonf(x)=7*x*4+6*x*
11、3-5*x*2+4*x+3df(x)=28*x*3+18*x*2-10*x+4read*,x0,e!x0=-1.0,e=0.0001x1=x0 x2=x1-f(x1)/df(x1)do while(abs(x1-x2)e)x1=x2 x2=x1-f(x1)/df(x1)end doprint*,x1,f(x1)end,2023/7/6,16,!函数子程序logical function su(n)su=.false.i=2m=sqrt(n*1.0)do while(mod(n,i)/=0.and.im.and.n1)su=.true.end,!主程序logical suinteger:num=
12、0,sum=0,maxdo n=100,9999 if(n999)then if(su(n).and.su(n/10).and.su(n/100).and.&su(n/1000)then num=num+1 sum=sum+n max=n end if else if(su(n).and.su(n/10).and.su(n/100)then num=num+1 sum=sum+n max=n end if end ifend doprint*,超级素数的个数:,numprint*,所有超级素数之和:,sumprint*,最大的超级素数:,maxend,运行结果:30755487393,2023/7/6,17,subroutine fsum(l,m)m=1do n=2,l/2 if(mod(l,n).eq.0)then m=m+n end ifend doend,do i=2,3000 call fsum(i,j)call fsum(j,k)if(i.eq.k).and.(i.ne.j)then print*,i,j end ifend doend,2023/7/6,18,