子程序的定义及使用.ppt_第1页
子程序的定义及使用.ppt_第2页
子程序的定义及使用.ppt_第3页
子程序的定义及使用.ppt_第4页
子程序的定义及使用.ppt_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

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

文档简介

第九讲子程序的定义及使用,9.1Fortran子程序概述,FORTRAN90子程序,也称过程,划分为两类:函数和子例行程序。函数是指产生一个运算结果且通过操作数调用执行的子程序。子例行程序是指可产生多个处理结果且通过CALL语句调用执行的子程序。每类子程序又划分为标准子程序和用户自定义子程序。用户自定义子程序又划分为内部子程序、外部子程序和模块子程序。FORTRAN90的子程序分类,使用标准函数需要注意以下几点:标准函数对变元的个数和类型有明确的规定和要求。要求有一个变元,如函数SIN(x);要求两个变元,如函数MOD(m,n);要求多个变元,如函数MAX(x1,x2,xn)。要求变元类型为整型,如函数MOD(m,n);,要求变元类型为实型,如SIND(x);要求变元类型为整型、实型、双精度、复型等多种类型,如ABS(x)。标准函数的函数值只有一个,且有明确的类型规定。多数函数函数值类型与变元类型相同,如函数SQRT(9.0D0)=3.0D0,类型都为双精度;也有函数函数值类型与变元类型不相同,如函数INT(8.5)=8,变元类型为实型,而函数值类型为整型。对于“弧度”和“角度”单位,使用不同的三角函数。函数变元必须写在函数名后括号内,变元可是常数、变量或表达式,少数标准函数变元要求变量,如LOG(v)IMPLICIT语句不能改变一个标准函数的类型。,9.2语句函数,一般形式为:F(x1,x2,xn)F为函数名,x1,x2,xn为虚拟变元(或称形式参数或哑元)。要求:不能重名,只能为普通变量名。类型可用隐含规则定义,也可用类型声明语句定义,但须放在该语句函数定义语句之前。下面程序通过语句函数实现例9.2问题。PROGRAMF72F(x1,x2,x3)=3.14159*(x1+x2/60.0+x3/3600.0)/180.0A=F(36.0,43.0,27.0)B=F(15.0,24.0,0.0)C=F(8.0,16.0,54.0)S=COS(A)*2-4*SIN(B)*TAN(C)WRITE(*,*)A,B,C,SENDprogram,调用一般形式为:语句函数名()说明:同语句函数定义语句中的语句函数名相同。为实在参数或实参,其个数、次序和类型应与定义语句中形式参数一致。实在参数之间用逗号分隔。实参可是常数、变量、数组元素、函数名、表达式。当调用语句函数时,其执行过程如下:首先计算实参表达式的值;将实参值赋予对应的形参,即形实参结合用被赋值的形参对语句函数定义语句中的表达式进行求值运算;将运算后的表达式值转换为函数名类型,并将其按函数值返回到调用位置。,使用语句函数的一些规定:一个语句函数只能在一行内定义。如果太长,可续行书写。语句函数定义语句是非执行语句。语句函数只有一个函数返回值,函数名与函数值符合赋值规则。定义语句函数,右端表达式中可调用已定义语句函数或标准函数,但不能调用该语句函数自己,即不能递归调用。H(x1,x2)=x1*x1+x2*x2F(x1,x2)=SQRT(H(x1,x2)语句函数的形式参数不允许为数组或下标变量或常量。DIMENSIONA(10),B(2,3)F1(x,y)=x+A(1)+y-B(1,2)!表达式中可以引用数组元素F(C)=C+100语句函数名属于局部变量,只能在定义它的程序单位中引用。语句函数可无形参,称为无参函数,圆括号不能省略,即:F()。,例9.1计算空间一点P(x,y,z)的方向弦,其计算公式如下:其中:、为点P到原点直线与坐标轴x、y、z的夹角。PROGRAMF7_1F(a,b,c,r)=rSQRT(a*a+b*b+c*c)WRITE(*,*)输入x,y,z:READ(*,*)x,y,zDAF(x,y,z,x)DBF(x,y,z,y)DGF(x,y,z,z)WRITE(*,*)DA,DB,DGENDprogram,9.3外部函数子程序,无法用一条语句来定义的函数,可以用一个单独的程序单位定义,它不属于调用函数语句所在的程序单位,因此称之为外部函数。是用户自定义的函数子程序。所在程序的其他程序单位都可以调用它。,PROGRAMmainINTEGERaddWrite(*,*)add(5,3)ENDPROGRAMmainFUNCTIONadd(m,n)INTEGERm,n,addadd=m+nENDFUNCTIONadd,FUNCTIONadd(m,n)INTEGERm,n,addadd=m+nENDFUNCTIONaddPROGRAMmainINTEGERaddWrite(*,*)add(5,3)ENDPROGRAMmain,关键字FUNCTION前面可指定内部数据类型,如:INTEGER、REAL、COMPLEX、CHARACTER或LOGICAL等。如果没指定,则按I-N规则或类型声明语句声明类型。称为哑元表;无形参时圆括号也不能省略。形参可以是变量名、数组名或子程序名函数体位于FUNCTION语句和ENDFUNCTION语句之间。函数体有说明部分、执行部分。当返回值只有一个时才能使用外部函数,并且外部函数名至少被赋值一次。,调用格式要求同标准函数、语句函数。作为操作数用。一般格式:F(a1,a2,an)F为函数名,ai为实在参数。实在参数可是表达式、普通变量、下标变量、数组名、内部函数引用、外部函数引用以及外部函数名和子程序名等。如果定义外部函数无形式参数,其引用形式为:F()。外部函数执行过程:若实在参数为表达式,则先对表达式求值。实在参数与相应的形式参数结合,将实参值传递给对应形参。经过形实结合,形式参数获得了所需要的值,然后,立即执行内部函数体。在执行函数体的过程中,若遇到RETURN语句或ENDFUNCTION语句,则控制返回到引用的地方,并代回所计算的函数值参加表达式的计算。,PROGRAMF971DIMENSIONA(6),B(4)WRITE(*,*)请输入A数组的6个元素和B数组的4个元素:READ(*,*)(A(I),I=1,6),(B(I),I=1,4)P5=pnx(5,A,2.5)P3=pnx(3,B,2.5)WRITE(*,100)2.5,P5,2.5,P3100FORMAT(1X,P5(,F3.1,)=,F10.5,P3(,F3.1,)=,F10.5)ENDprogram,输入数据:5.0,2.5,0.0,0.0,4.4,3.53.4,1.5,1.76,3.5输出结果:P5(2.5)=600.43750P3(2.5)=70.40000,9.4外部子程序,FORTRAN90提供标准子程序、语句函数、外部子程序(外部函数、外部子例行程序)等。外部子程序是一个独立的程序单元。,95,PROGRAMmy_addINTEGERm,n,sm=4n=5calladd(m,n,s)write(*,*)swrite(*,*)mENDPROGRAMmy_addSUBROUTINEadd(m,n,s)INTEGERm,n,ss=m+nm=m+1ENDSUBROUTINEadd,外部子例行程序,简称外部子程序,也称外部过程,是独立的程序单元。外部子例行程序可产生多个结果,由参数返回。外部子例行程序定义一般格式:SUBROUTINE子程序名()ENDSUBROUTINE例如:SUBROUTINEswap(x,y)INTEGERtemp,x,ytemp=x;x=y;y=tempENDSUBROUTINEswap,定义子程序应遵守的规则:(1)当要求的返回值多于一个时才使用子例行程序。其返回值通过实在参数与虚拟参数的结合进行。(2)外部子例行程序的定义是一个程序单元,有说明部分和执行部分,尾部必须有END结束。(3)外部子例行程序在整个程序有意义。(4)子例行程序定义中的虚参表可以是变量名、数组名、函数名或子程序名,另外在子例行程序中还可以用星号(*)作为虚参。,子例行程序不指定数据类型,子程序名不返回值。称为哑元表,无形参,则圆括号可省略。子程序体位于SUBROUTINE和ENDSUBROUTINE语句之间。说明部分:说明函数名、形参、变量等类型。执行部分:进行数值运算或数据处理。例:计算X=2.5时多项式值P5(x)5.0 x5+2.5x4+4.4x+3.5P3(x)3.4x3+1.5x2+1.76x+3.5调用计算CALLpnf(5,A,2.5,pnx)WRITE(*,*)pnxCALLpnf(3,A,2.5,pnx)WRITE(*,*)pnx,通过CALL语句调用。作为语句使用。一般格式:CALLP(a1,a2,an)或CALLP。如果无虚拟参数,其调用形式为:CALLP。外部子例行程序执行过程:若实在参数为表达式,则先对表达式求值。实在参数与相应的虚拟参数结合,将实参值或地址传递给对应虚参。经过哑实结合,形式参数获得了所需要的值或地址。执行子程序体。返回调用处下一条语句执行。,使用外部子例行程序求矩阵A的转置矩阵B。PROGRAMmatrixPARAMETER(N=3)INTEGERA(N,N),B(N,N)READ(*,*)(A(I,J),J=1,N),I=1,N)CALLtrans(N,A,B)DOI=1,NWRITE(*,(I3,1X)A(I,1:N)ENDDOENDPROGRAMmatrix,!求转置矩阵SUBROUTINEtrans(N,A,B)INTEGEEA(N,N),B(N,N),NINTEGERI,JDOI=1,NDOJ=1,NB(J,I)=A(I,J)ENDDOENDDOENDSUBROUTINEtrans,9.5实参与虚参之间的数据传递关系,函数子程序和子例行程序中的虚参可以是变量名、数组名、函数名、子例行程序名。在子例行程序中还可以用星号(*)作为虚参当函数子程序和子例行程序被调用之前,所有虚参都无定义,既没有具体的存储单元也没有具体的值。Fortran90的虚实结合规则是:第一个实参与第一个虚参结合,第二个实参与第二个虚参结合,以此类推;且要求实参与虚参要个数相等,类型一致。子程序在调用执行过程中,虚参才有具体数据。子程序调用结束后,虚参又变得无定义。实参和虚参之间的数据传递关系有两种:引用传递和值传递。引用传递是将实参的地址传递给对应虚参。引用传递也称地址传递。值传递是将实参的值传递给对应虚参,即实参和虚参占用不同的存储空间,在子程序中改变虚参的值不影响实参的值。,表8-1虚拟参数与实在参数的结合关系虚拟参数实在参数结合方式普通变量常数,常量,标准函数、语句函数,内部函数,外部函数值传递普通变量普通变量名,数组元素引用传递非字符数组非字符数组名,非字符数组元素引用传递字符数组字符数组名,字符数组元素引用传递函数外部函数(EXTERNAL),标准函数(INTRINSIC)引用传递子例行程序子程序名(EXTERNAL)引用传递“*”*语句标号值(标号值),当虚参是变量时,对应的实参可以是同一类型的常量、变量、数组元素和表达式。如果实参是变量或数组元素,调用子程序时,实参和虚参的传递关系是引用传递。对应虚参与实参共用存储单元。实参为常数、常量或表达式,则按值传递方式进行哑实结合。调用子程序时,对实参求值,并将结果传递给对应形参。子程序中一般不对这类虚参进行赋值,赋值也不会对子程序外部产生影响。虚参为字符变量,则虚参的长度定义必须遵守两条规则之一(1)虚参字符变量的长度定义必须小于等于对应实参变量的长度。(2)虚参字符变量长度可用(*)来定义,表示长度不定。,当虚参是数组名时,此数组称为形式数组,对应的实参可以是同一类型的数组名或数组元素。(1)如果虚参数组是数值类型或逻辑类型,并且对应实参也是相同的类型,则将实在数组第一个元素存储地址传递给形式数组,即形式数组第一个元素与实在数组第一个元素结合,其它数组元素按存储顺序依次结合,访问形式数组元素相当于访问实在数组对应元素。形式数组的大小不能超过实在数组的大小。(2)如果虚参数组是数值类型或逻辑类型,并且对应实参也是相同的类型的数组元素。则将数组元素存储地址传递给形式数组,即形式数组第一个元素与实在数组元素结合,其它数组元素按存储顺序依次结合,访问形式数组元素相当于访问实在数组对应元素。形式数组大小不能超过实在数组大小。(3)当数组是字符类型时,虚参和实参数组不是按数组元素的顺序一一结合,而是按字符位置一一对应结合。虚参数组中允许的字符总数必须小于等于实参数组中允许的字符总数,Subroutineread_matrix(n,a,filename)Character*(*)filenameDimensiona(n,n)Open(10,file=filename,status=old)Read(10,*)DoI=1,nRead(10,*)(a(I,j),j=1,n)EnddoClose(10)Endsubroutine,(4)子程序中允许虚参数组是可调数组。可调数组名必须是虚参。可调数组用子程序的整形虚参来说明数组每维的上下界。每次调用时,通过整形虚参对应的实参来决定可调数组的大小。可调数组也遵循前述1、2、3中的规定。(5)其他虚参数组中最后一维的上界可以用星号(*)表示,虚参允许为函数名或子例行程序名,称为形式函数或形式子例行程序,统称形式子程序,可在函数体或子程序体中调用形式子程序。(1)实参为外部子程序,则需通过EXTERNAL外部语句声明。EXTERNALpname,pname,pname实参为标准函数,则需通过INTRINSIC内部语句进行声明。INTRINSICfname,fname,fnamePROGRAMexamINTRINSICSINEXTERNALfun,proc,prtREALfun,f1f1=fun(3.1415926/6,SIN),星号也可以作为虚参。对应的实参必须是一个冠有*号的语句标号。星号作形式参数是为该程序单位中出现的RETURN语句提供一个选择返回的机制。在虚参表中可出现多个“*”,按出现的顺序用自然数编号,最小编号为1,最大编号由出现在SUBROUTINE语句形参表中星号的个数而定。READ(*,*)a,bCALLsub(a,b,x,y,*100,*15,2)100WRITE(*,*)a,b,x,y15WRITE(*,*)a,b,x,y,9.6递归子程序,在FORTRAN90中新增了递归子程序功能。所谓递归子程序是指允许子程序体内直接或间接地调用子程序自身的子程序。称这种子程序调用为递归调用。递归子程序有两种:递归函数和递归子例行程序。对于递推公式或递归问题,可使用递归子程序实现。如n!可表示为递推公式n*(n-1)!,可使用递归函数求解阶乘。递归子程序定义类似于普通子程序定义,不同之处是在FUNCTION或SUBROUTINE语句前加一个RECURSIVE关键字前缀。对于递归函数,如果是直接调用(也就是函数名出现在函数体内),就必须在FUNCTION语句之后加一个RESULT子句。,RECURSIVESUBROUTINEfactorial(m,fact)INTEGERfact,mIF(m=1)THENfact=1ELSECALLfactorial(m-1,fact)fact=m*factENDIFEND

温馨提示

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

评论

0/150

提交评论