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

下载本文档

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

文档简介

第九讲 子程序的定义及使用 9.1 Fortran 子程序概述 lFORTRAN 90子程序,也称过过程,划分为为两类类:函数和子例行程序。 l函数是指产产生一个运算结结果且通过操作数调调用执执行的子程序。 l子例行程序是指可产产生多个处处理结结果且通过过CALL语语句调调用执执行的子 程序。 l每类类子程序又划分为标为标 准子程序和用户户自定义义子程序。 l用户户自定义义子程序又划分为为内部子程序、外部子程序和模块块子程序 。 lFORTRAN 90的子程序分类类 FORTRAN 90 子程序 子例行程序 标准子例行程序 用户自定义子例行程序 内部子例行程序 外部子例行程序 模块子例行程序 函数 标准函数 用户自定义函数 内部函数 外部函数 模块函数 语句函数 标准子程序 内部子程序 外部子程序 模块子程序 标准子程序 内部子程序 外部子程序 模块子程序 使用标准函数需要注意以下几点: l标准函数对变元的个数和类型有明确的规定和要求。要求有一个 变元,如函数SIN(x);要求两个变元,如函数MOD(m,n);要求多个 变元,如函数MAX(x1,x2,xn)。要求变元类型为整型,如函数 MOD(m,n);,要求变元类型为实型,如SIND(x);要求变元类型为 整型、实型、双精度、复型等多种类型,如ABS(x)。 l标准函数的函数值只有一个,且有明确的类型规定。多数函数函 数值类型与变元类型相同,如函数SQRT(9.0D0)=3.0D0,类型都为 双精度;也有函数函数值类型与变元类型不相同,如函数 INT(8.5)=8,变元类型为实型,而函数值类型为整型。 l对于“弧度”和“角度”单位,使用不同的三角函数。 l函数变元必须写在函数名后括号内,变元可是常数、变量或表达 式,少数标准函数变元要求变量,如LOG(v) lIMPLICIT语句不能改变一个标准函数的类型。 9.2 语句函数 在求解实际问题时,特别是在求解有关科学与工程数值 计算问题时,常常会遇到计算一些数学表达式,如: 这些数学表达式在程序中多次出现,需要重复书写它们, 不但浪费了宝贵的时间和精力,而且也容易出错。任何数学 表达式实际上都可表示成一元、二元或多元函数关系,即 F(x1,x2,xn),这些函数关系如果没有对应的标准函数,则 需要用户设法定义新的函数来实现它们。 FORTRAN 90提供了语句函数定义功能来定义一些简单的 函数,用于实现有关的函数关系。用户自定义语句函数其使 用方法与标准函数相同,可以作为操作数在表达式中调用。 一般形式为:F(x1,x2,xn) F为函数名,x1,x2,xn为虚拟变元(或称形式参数或哑元)。 要求:不能重名,只能为普通变量名。类型可用隐含规则定义 ,也可用类型声明语句定义,但须放在该语句函数定义语句之 前。 下面程序通过语句函数实现例9.2问题。 PROGRAM F72 F(x1,x2,x3)=3.14159*(x1+x2/60.0+x3/3600.0)/180.0 A=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,S END program 调用一般形式为: 语句函数名() 说明: l同语句函数定义语句中的语句函数名相同。 l为实在参数或实参,其个数、次序和类型应与定 义语句中形式参数一致。实在参数之间用逗号分隔。 l实参可是常数、变量、数组元素、函数名、表达式。 当调用语句函数时,其执行过程如下: l首先计算实参表达式的值; l将实参值赋予对应的形参,即形实参结合 l用被赋值的形参对语句函数定义语句中的表达式进行求值运 算; l将运算后的表达式值转换为函数名类型,并将其按函数值返回 到调用位置。 使用语句函数的一些规定: l一个语句函数只能在一行内定义。如果太长,可续行书写。 l语句函数定义语句是非执行语句。 l语句函数只有一个函数返回值,函数名与函数值符合赋值规 则。 l定义语句函数,右端表达式中可调用已定义语句函数或标准函 数,但不能调用该语句函数自己,即不能递归调用。 H(x1,x2)=x1*x1+x2*x2 F(x1,x2)=SQRT(H(x1,x2) l语句函数的形式参数不允许为数组或下标变量或常量。 DIMENSION A(10),B(2,3) F1(x,y)=x+A(1)+y-B(1,2) !表达式中可以引用数组元素 F(C)=C+100 l语句函数名属于局部变量,只能在定义它的程序单位中引用。 l语句函数可无形参,称为无参函数,圆括号不能省略,即:F() 。 例9.1计算空间一点P(x,y,z)的方向弦,其计算公式如下: 其中:、为点P到原点直线与坐标轴x、y、z的夹角。 PROGRAM F7_1 F(a,b,c,r)=rSQRT(a*a+b*b+c*c) WRITE(*,*) 输入 x,y,z: READ(*,*) x,y,z DAF(x,y,z,x) DBF(x,y,z,y) DGF(x,y,z,z) WRITE(*,*) DA,DB,DG END program 9.3 外部函数子程序 l无法用一条语句来定义的函数,可以用一个单独的 程序单位定义,它不属于调用函数语句所在的程序 单位,因此称之为外部函数。 l是用户自定义的函数子程序。所在程序的其他程序 单位都可以调用它。 PROGRAM main INTEGER add Write(*,*) add(5,3) END PROGRAM main FUNCTION add(m,n) INTEGER m,n,add add=m+n END FUNCTION add FUNCTION add(m,n) INTEGER m,n,add add=m+n END FUNCTION add PROGRAM main INTEGER add Write(*,*) add(5,3) END PROGRAM main l外部函数只产生一个结果,由函数名返回。 l外部函数定义一般格式: 类型说明 FUNCTION 函数名(形式参数表) 说明语句部分 执行语句部分 END FUNCTION 函数名 例如: INTEGER FUNCTION add(m,n) INTEGER m,n add=m+n END FUNCTION add FUNCTION add(m,n) INTEGER m,n,add add=m+n END FUNCTION add l关键字FUNCTION前面可指定内部数据类型,如:INTEGER、 REAL、COMPLEX、CHARACTER或LOGICAL等。如果没指定,则按I- N规则或类型声明语句声明类型。 l称为哑元表;无形参时圆括号也不能省略。形参 可以是变量名、数组名或子程序名 l函数体位于FUNCTION语句和END FUNCTION语句之间。 l函数体有说明部分、执行部分。 l当返回值只有一个时才能使用外部函数,并且外部函数名至 少被赋值一次。 l调用格式要求同标准函数、语句函数。作为操作数用。 l一般格式:F(a1,a2,an)F为函数名,ai为实在参数。 l实在参数可是表达式、普通变量、下标变量、数组名、内部 函数引用、外部函数引用以及外部函数名和子程序名等。 l如果定义外部函数无形式参数,其引用形式为:F( )。 l外部函数执行过程: n若实在参数为表达式,则先对表达式求值。 n实在参数与相应的形式参数结合,将实参值传递给对应形参 。 n经过形实结合,形式参数获得了所需要的值,然后,立即执行 内部函数体。 n在执行函数体的过程中,若遇到RETURN语句或END FUNCTION 语句,则控制返回到引用的地方,并代回所计算的函数值参 加表达式的计算。 PROGRAM F971 DIMENSION A(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,P3 100 FORMAT(1X,P5(,F3.1,)=,F10.5,P3(,F3.1,)=,F10.5) END program 输入数据: 5.0,2.5,0.0,0.0,4.4,3.5 3.4,1.5,1.76,3.5 输出结果: P5(2.5)= 600.43750 P3(2.5)= 70.40000 9.4 外部子程序 lFORTRAN90提供标准子程序、语句函数、外部 子程序(外部函数、外部子例行程序)等。 l外部子程序是一个独立的程序单元。 9 5 PROGRAM my_add INTEGER m,n,s m=4 n=5 call add(m,n,s) write(*,*) s write(*,*) m END PROGRAM my_add SUBROUTINE add(m,n,s) INTEGER m,n,s s=m+n m=m+1 END SUBROUTINE add l外部子例行程序,简称外部子程序,也称外部过程,是 独立的程序单元。 l外部子例行程序可产生多个结果,由参数返回。 l外部子例行程序定义一般格式: SUBROUTINE 子程序名() END SUBROUTINE 例如: SUBROUTINE swap(x,y) INTEGER temp,x,y temp=x;x=y;y=temp END SUBROUTINE swap 定义子程序应遵守的规则: (1)当要求的返回值多于一个时才使用子例行程 序。其返回值通过实在参数与虚拟参数的结合进行。 (2)外部子例行程序的定义是一个程序单元,有 说明部分和执行部分,尾部必须有END结束。 (3)外部子例行程序在整个程序有意义。 (4)子例行程序定义中的虚参表可以是变量名、 数组名、函数名或子程序名,另外在子例行程序中还 可以用星号(*)作为虚参。 l子例行程序不指定数据类型,子程序名不返回值。 l称为哑元表, 无形参,则圆括号可省略。 l子程序体位于SUBROUTINE和END SUBROUTINE语句之间。 l说明部分:说明函数名、形参、变量等类型。 l执行部分:进行数值运算或数据处理。 l例:计算X=2.5时多项式值 P5(x)5.0x5+2.5x4+4.4x+3.5 P3(x)3.4x3+1.5x2+1.76x+3.5 调用计算 CALL pnf(5,A,2.5,pnx) WRITE(*,*) pnx CALL pnf(3,A,2.5,pnx) WRITE(*,*) pnx l通过CALL语句调用。作为语句使用。 l一般格式:CALL P(a1,a2,an)或CALL P。 l如果无虚拟参数,其调用形式为:CALL P。 l外部子例行程序执行过程: n若实在参数为表达式,则先对表达式求值。 n实在参数与相应的虚拟参数结合,将实参值 或地址传递给对应虚参。 n经过哑实结合,形式参数获得了所需要的值 或地址。 n执行子程序体。 n返回调用处下一条语句执行。 使用外部子例行程序求矩阵A的转置矩阵B。 PROGRAM matrix PARAMETER(N=3) INTEGER A(N,N),B(N,N) READ(*,*) (A(I,J),J=1,N),I=1,N) CALL trans(N,A,B) DO I=1,N WRITE(*,(I3,1X) A(I,1:N) ENDDO END PROGRAM matrix !求转置矩阵 SUBROUTINE trans(N,A,B) INTEGEE A(N,N),B(N,N),N INTEGER I,J DO I=1,N DO J=1,N B(J,I)=A(I,J) ENDDO ENDDO END SUBROUTINE trans 9.5 实参与虚参之间的数据传递关系 l函数子程序和子例行程序中的虚参可以是变量名、数组名、函 数名、子例行程序名。 l在子例行程序中还可以用星号(*)作为虚参 l当函数子程序和子例行程序被调用之前,所有虚参都无定义, 既没有具体的存储单元也没有具体的值。 lFortran 90的虚实结合规则是:第一个实参与第一个虚参结合 ,第二个实参与第二个虚参结合,以此类推;且要求实参与虚 参要个数相等,类型一致。 l子程序在调用执行过程中,虚参才有具体数据。子程序调用结 束后,虚参又变得无定义。 l实参和虚参之间的数据传递关系有两种:引用传递和值传递。 引用传递是将实参的地址传递给对应虚参。引用传递也称地址 传递。 l值传递是将实参的值传递给对应虚参,即实参和虚参占用不同 的存储空间,在子程序中改变虚参的值不影响实参的值。 表8-1 虚拟参数与实在参数的结合关系 虚拟参数 实在参数 结合方式 普通变量 常数,常量,标准函数、语句函数,内部函数,外部函数 值传递 普通变量 普通变量名,数组元素 引用传递 非字符数组 非字符数组名,非字符数组元素 引用传递 字符数组 字符数组名,字符数组元素 引用传递 函数 外部函数(EXTERNAL),标准函数(INTRINSIC) 引用传递 子例行程序 子程序名(EXTERNAL) 引用传递 “*” *语句标号 值(标号 值) l当虚参是变量时,对应的实参可以是同一类型的常量、变量 、数组元素和表达式。 l如果实参是变量或数组元素,调用子程序时,实参和虚参的 传递关系是引用传递。对应虚参与实参共用存储单元。 l实参为常数、常量或表达式,则按值传递方式进行哑实结合 。调用子程序时,对实参求值,并将结果传递给对应形参。 子程序中一般不对这类虚参进行赋值,赋值也不会对子程序 外部产生影响。 l虚参为字符变量,则虚参的长度定义必须遵守两条规则之一 (1)虚参字符变量的长度定义必须小于等于对应实参变量 的长度。(2)虚参字符变量长度可用(*)来定义,表示长度 不定。 l当虚参是数组名时,此数组称为形式数组,对应的实参可以是 同一类型的数组名或数组元素。 (1)如果虚参数组是数值类型或逻辑类型,并且对应实参也是 相同的类型,则将实在数组第一个元素存储地址传递给形式数 组,即形式数组第一个元素与实在数组第一个元素结合,其它数 组元素按存储顺序依次结合,访问形式数组元素相当于访问实 在数组对应元素。形式数组的大小不能超过实在数组的大小。 (2)如果虚参数组是数值类型或逻辑类型,并且对应实参也是 相同的类型的数组元素。则则将数组元素存储地址传递给形式数 组,即形式数组第一个元素与实在数组元素结合,其它数组元素 按存储顺序依次结合,访问形式数组元素相当于访问实在数组 对应元素。形式数组组大小不能超过实过实 在数组组大小。 (3)当数组是字符类型时,虚参和实参数组不是按数组元素的 顺序一一结合,而是按字符位置一一对应结合。虚参数组中允 许的字符总数必须小于等于实参数组中允许的字符总数 Subroutine read_matrix(n,a,filename) Character*(*) filename Dimension a(n,n) Open(10,file=filename,status=old) Read(10,*) Do I=1,n Read(10,*)(a(I,j),j=1,n) End do Close(10) End subroutine (4)子程序中允许虚参数组是可调数组。 l可调数组名必须是虚参。 l可调数组用子程序的整形虚参来说明数组每维的上 下界。每次调用时,通过整形虚参对应的实参来决 定可调数组的大小。 l可调数组也遵循前述1、2、3中的规定。 (5)其他 l虚参数组中最后一维的上界可以用星号(*)表示 l虚参允许为函数名或子例行程序名,称为为形式函数或形式子 例行程序,统统称形式子程序,可在函数体或子程序体中调调用形 式子程序。 l(1)实参为外部子程序,则需通过EXTERNAL外部语语句声明。 EXTERNAL pname,pname,pname l实参为标准函数,则则需通过过INTRINSIC内部语语句进进行声明。 INTRINSIC fname,fname,fname PROGRAM exam INTRINSIC SIN EXTERNAL fun,proc,prt REAL fun,f1 f1=fun(3.1415926/6,SIN) l星号也可以作为虚参。对应的实参必须是一个冠有*号的 语句标号。 l星号作形式参数是为该程序单位中出现的RETURN语句提 供一个选择返回的机制。 l在虚参表中可出现现多个“*”,按出现现的顺顺序用自然数编编 号,最小编编号为为1,最大编编号由出现现在SUBROUTINE语语句形 参表中星号的个数而定。 READ(*,*) a,b CALL sub(a,b,x,y,*100,*15,2) 100 WRITE(*,*) a,b,x,y 15WRITE(*,*) a,b,x,y 9.6 递归子程序 l在FORTRAN 90中新增了递归子程序功能。所谓递归 子程序是指允许子程序体内直接或间接地调用子程 序自身的子程序。称这种子程序调用为递归调用。 递归子程序有两种:递归函数和递归子例行程序。 对于递推公式或递归问题,可使用递归子程序实现。 如n!可表示为递推公式n*(n-1)!,可使用递归函数 求解阶乘。 l递归子程序定义类似于普通子程序定义,不同之处是 在FUNCTION或SUBROUTINE语句前加一个RECURSIVE关 键字前缀。对于递归函数,如果是直接调用(也就是 函数名出现在函数体内),就必须在FUNCTION语句之 后加一个RESULT子句。 RECURSIVE SUBROUTINE factorial(m,fact) INTEGER fact,m IF (m=1) THEN fact=1 ELSE CALL factorial(m-1,fact) fact=m*f

温馨提示

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

评论

0/150

提交评论