第2章 Fortran程序设计基础.ppt

上传人:创****公 文档编号:1593474 上传时间:2019-10-19 格式:PPT 页数:118 大小:704.50KB
返回 下载 相关 举报
第2章 Fortran程序设计基础.ppt_第1页
第1页 / 共118页
第2章 Fortran程序设计基础.ppt_第2页
第2页 / 共118页
点击查看更多>>
资源描述

《第2章 Fortran程序设计基础.ppt》由会员分享,可在线阅读,更多相关《第2章 Fortran程序设计基础.ppt(118页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、第6章 子程序,子程序是构造大型程序的有效工具,一个实用程序(不管是系统程序还是应用程序),一般都含有多个子程序。FORTRAN 90 中的子程序按子程序完成的功能划分有子例行程序、函数子程序、数据块子程序等,按是否定义在某个特定的程序单元内部来划分有程序单元子程序、模块子程序以及内部(INTERNAL)子程序等,这些通称为子程序。子程序不能独立运行,它们和一种称为主程序(就是本章前读者已经熟知的程序结构)的程序单元一起组成一个实用程序。一个程序可以不含子程序,但不能缺少主程序。本章讨论各种子程序的结构、功能以及子程序与主程序或子程序之间的数据交互作用。语句函数不具备子程序的一般书写特征,但其

2、作用与子程序相同,也一并放在本章讨论。通过本章的学习,读者应能熟练地选择并设计恰当的子程序形式来构造自己的程序,从而提高程序设计能力。,语句函数,SIN(X)、SQRT(X)等由FORTRAN编译器提供的函数为内在函数。这些内在函数是在程序设计过程中使用频率很高,并且一般实现比较复杂的函数。用户在使用内在函数时,并不需要对函数的实现过程进行描述,只需按照FORTRAN 90手册要求使用即可,FORTRAN 90编译器“认识”这些内在函数并能正确完成函数所规定的功能。在实际设计过程中,用户还会遇到大量的并未包含在内在函数中的其他函数,计算这些函数时,就不能象内在函数那样仅仅使用函数名来使用这些函

3、数,而必须在适当的地方以FORTRAN 90能“理解”的形式向FORTRAN 90 编译器说明这些非内在的函数的计算过程与参数类型,当函数的计算过程简单到可以用一个语句定义清楚时,这样的定义语句就称为语句函数。,例 6.1 设多项式函数设计一个程序,计算f(1)、f(10)、f(12)、f(-5)的值。程序如PROGRAM EXAM1A :,PROGRAM EXAM1A X=1 FX=5*X*3-2*X*2+7*X+6 WRITE(*,*)f(,X,)=,FX X=10 FX=5*X*3-2*X*2+7*X+6 WRITE(*,*)f(,X,)=,FX,X=12 FX=5*X*3-2*X*2+

4、7*X+6 WRITE(*,*)f(,X,)=,FX X=-1 FX=5*X*3-2*X*2+7*X+6 WRITE(*,*)f(,X,)=,FXEND,显然,程序EXAM1A不简练,把一个相同的函数表达式重复了多遍,如果能定义一个函数f(x),然后分别使用1、10等参数来调用f(x),将会有效的简化程序量,这就是本节要讨论的内容。,611 语句函数的定义,如前所述,由于FORTRAN 90 的编译器不“认识”一般的函数f(x),不知道怎样计算f(x)的函数值,因而,在使用(称为函数调用)函数时,必须向FORTRAN 90编译器说明该函数的计算方法,这种说明过程称为函数定义。语句函数定义的一般

5、格式是:,1.语句函数名在语句函数定义格式中,f称为函数名,函数名的组成规则与变量名相同。如果没有在语句函数定义语句前用类型语句说明该函数名的数据类型,则该语句函数的函数值的类型按其函数名遵守IN隐含规则。如f函数隐含为实型函数,而nf则隐含为整形函数。F(X,Y)=X*2+Y*2 ! 定义了一个实型函数FINTEGER F(X,Y)=X*2+Y*2 ! 定义了一个整型函数F NF(X,Y)=X*2+Y*2 ! 也同样定义了一个整型函数F 语句函数不能与同一个程序单元中的变量同名。,2.语句函数的虚参在语句函数定义语句中的函数参数称为虚参,他们本身是没有值的,只有在函数调用时才用实际参数(称为

6、实参)代替。实参或是常数、或是一个有确定值的变量、或是一个可以计算值的表达式。虚参在形式上与普通变量相同,一个语句函数中的虚参不能同名。不同语句函数中的虚参可以同名,虚参也可以和程序中的变量同名。当没有语句对虚参的数据类型进行说明时,虚参的类型遵守IN隐含规则;当使用了类型说明语句对虚参类型进行说明后,这种说明对于虚参以及与虚参同名的变量同时有效。INTEGER ZF(X)=3*X*2+5G(Y)=3*Y*2+5H(Z)=3*Z*2+5在上述程序中,函数F和G本质上是一个函数,因为对于任意的实参T,F(T)和G(T)总是相同的,但函数F、G和H有点不同,其虚参Z被说明为整型。当虚参个数多于一个

7、时,虚参间用逗号分隔,当没有虚参时(这样的语句函数没有使用价值),函数名后的括弧也不能省略。,3.语句函数表达式 语句函数表达式说明函数与参数的对应关系,在函数表达式中,可以包含常量、变量、函数虚参(虚参必须包含在表达式中)、FORTRAN 90内在函数、数组以及前面已经说明了的语句函数。 4.关于语句函数的进一步说明 (1)只有当函数关系简单,可以用一个语句描述函数与参数的对应关系时,才能使用语句函数。 (2)语句函数是非执行语句,语句函数的定义语句要放在一个程序单位的所有其他说明语句之后,并放在所有可执行语句之前。 (3)语句函数只有在本程序单元中才有意义。也就是说,不能使用其他程序单元中

8、的语句函数。 (4)语句函数中的虚参必须是变量,不能是常量、数组元素和内在函数等。 (5)语句函数是有类型的,因而语句函数表达式的类型一定要和其函数名的类型相容,612 语句函数的调用,语句函数一经定义,就可以在同一个程序单元中调用它,调用的形式和内在函数完全相同。函数调用要注意以下两个问题:1调用时可以使用常量、变量、内在函数以及它们的表达式作为实参代替对应的虚参位置,但要保证实参与虚参具有完全相同的类型,并且实参是可以计算值的 (即调用前实参中包含的变量全部已经赋值。)2实参和虚参个数相同。例 6.2 用函数语句的方法设计例6.1PROGRAM EXAM1B INTEGER X F(X)=

9、5*X*3-2*X*2+7*X+6 WRITE(*,*)F(2),F(10),F(12),F(-2)END,6.2 函数子程序,语句函数由于要求在一个语句中完成函数的定义,因而它只能解决一些较简单的问题,当函数关系比较复杂,用一个语句无法定义时,语句函数就无能为力了,这时需要用到函数子程序。,621 函数子程序的定义,函数子程序是以保留字 FUNCTION 开头,并以保留字 END结束的一个程序段,该程序段可以独立存储为一个文件,也可以和调用它的程序单元合并存储为一个程序文件。函数子程序的定义格式是:类型说明 FUNCTION 函数名(虚参表) 函数体END函数名的命名方法与变量名相同,虚参可

10、以是简单变量和数组变量,但不能是常数、数组元素、表达式),例 6.3 编程,求:,分析:上述三个数列的通项不同,求和范围也不同,用一个程序段难以同时计算三个数列的和,并且,因为无法用一个语句函数完成数列的求和计算,所以也无法使用语句函数来简化程序设计。,FUNCTION SM(M,N,L) SM=0 DO I=M,N IF (L0) THEN SM=SM+I*L ELSE SM=SM+(1.0*I)*L !进行实型运算 END IF ENDDO END FUNCTION SM,PROGRAM EXAM2 !开始主程序单元定义WRITE(*,*)S1=,SM(1,100,2) !调用函数子程序S

11、M完成S1的计算WRITE(*,*)S2=,SM(100,140,3)WRITE(*,*)S3=,SM(20,50,-1)END程序运行结果如下: S1= 338350.000000 S2= 7.291440E+07 S3= 9.514656E-01对程序EXAM2作如下说明:程序的第一部分是函数子程序的定义部分,如前所述,它可以单独存储为一个程序文件。从保留字PROGRAM开始至END是主程序部分,一个程序总是从主程序开始运行的,主程序的第24个语句都要打印函数SM的值,这时调用函数定义部分,根据函数的定义描述计算函数的值并予以打印。三个打印语句分别调用了三次函数子程序(即执行了三次函数子程

12、序)。,采用函数子程序设计程序时并没有提高程序的执行效率,但却可以有效的提高程序的设计效率。当函数子程序的定义过程和主程序放到一个程序文件中时,存储顺序是任意的,函数子程序可以放到主程序之前(如EXAM2),也可以放到主程序之后,但是程序总是从主程序开始执行。,REAL FUNCTION SM(M,N,L)IMPLICIT NONEINTEGER:M,N,L, JREAL:I(M:N)FORALL(J=M:N) I(J)=JSM=SUM(I*L)END FUNCTION SM,例:程序的优化,FUNCTION SM(M,N,L) SM=0 DO I=M,N IF (L0) THEN SM=SM

13、+I*L ELSE SM=SM+(1.0*I)*L END IF ENDDO END FUNCTION SM,函数定义部分应注意如下问题:1函数值的类型可以在函数定义时予以说明,下面的两种说明方法是等效的:(1)INTEGER FUNCTION F1(X1,X2.XN)函数体END(2)FUNCTION F1(X1,X2.XN)INTEGER F1函数体END都说明F1是一个整型函数,当未使用这种显示的类型说明时(如例6.3),函数值的类型遵守IN隐含规则。,2 函数不能有同名虚参。虚参的类型可以在函数体中进行说明方法,当未对虚参类型进行说明时,虚参类型遵守IN隐含规则。3 函数定义部分中一定

14、要有一个语句将函数值赋值给函数名(如例6.3中的第5句和第7句)。这种赋值语句的格式是: 函数名=表达式注意不要在函数名后带上括弧,写成: 函数名(虚参表)=表达式,622 函数子程序的调用,定义函数子程序的目的是为了调用。不仅主程序可以调用一个函数子程序,函数子程序也可以调用其它的函数子程序,甚至于还可以调用本身(递归调用)。调用程序称为主调程序单元,而被调用的函数子程序称为被调程序单元。调用一个函数子程序的方法和调用内在函数和语句函数的方法基本相同:1 调用时应该用实参代替函数子程序定义部分的虚参,实参和虚参的类型要相同。 和语句函数一样,实参可以是常量、变量、表达式等。2 调用程序单位中

15、的变量不能与函数子程序同名。函数值的类型由函数定义程序单元决定,与调用程序单元无关。3 当函数名的类型不满足IN隐含规则时,在调用程序单元中要对函数名的类型给出说明(如例 8.4 中的主程序EXAM3的第2句。)4 不能调用一个没有定义的函数子程序(这一点和内在函数是不同的。),例 6.4 用函数子程序的方法设计一个程序,求50100内的所有素数及其和。,分析:设计一个函数子程序 PRIME(N),函数PRIME的值定义如下:,主程序的任务是应用PRIME函数子程序在50100之间使用枚举法求出那些使PRIME函数值为1的自然数并求这些数的和。,函数子程序如下:FUNCTION PRIME(N

16、)INTEGER PRIME * 定义PRIME是整型函数PRIME=0DO I=2,N-1 IF (MOD(N,I)=0) GOTO 10 * 参数N有因子I,非素数,退出循环ENDDOPRIME=1 * 参数N无任何因子,函数值为110 END,主程序如下:PROGRAM EXAM3INTEGER PRIME * 说明要调用的函数PRIME 为整型DO I=50,100 IF (PRIME(I)=1) THEN S=S+IWRITE(*,*)I END IFEND DOWRITE(*,*)S=,SEND运行结果如下: . 83 89 97 S= 732.000000,PROGRAM EXA

17、M3INTEGER: PRIME, index(50:100)DO I=50,100 index(i)=PRIME(I)*iEND DOWRITE(*,*)S=,Sum(index)END,例:程序的优化,PROGRAM EXAM3INTEGER PRIMEDO I=50,100 IF (PRIME(I)=1) THEN S=S+IWRITE(*,*)I END IFEND DOWRITE(*,*)S=,SEND,例 6.5 当一个数各个数位的立方和等于这个数本身时,称这样的数为水仙花数(如153=1*3+5*3+3*3,所以,153是一个水仙花数,)编程:求100999之间的水仙花数。分析:

18、设计一个函数子程序NUM(N,I),当I=100时,函数NUM返回N的百位上的数;当I=10时,NUM返回N的十位上的数,I=1时,NUM返回N的个位上的数。主程序中调用NUM函数在100999之间找出所有水仙花数。,PROGRAM FLOWER DO I=100,999 IF (NUM(I,100)*3+NUM(I,10)*3+NUM(I,1)*3=I) THEN WRITE(*,*)I ENDIF ENDDOEND,FUNCTION NUM(N,I) SELECT CASE(I) CASE(100) NUM=N/100 !用N百位上的数赋值给函数名CASE(10) NUM=MOD(N/10

19、,10) !用N十位上的数赋值给函数名CASE(1) NUM=MOD(N,10) !用N个位上的数赋值给函数名 END SELECTEND程序运行结果如下: 153 370 371 407,题目6.1 设计一个求向量叉乘的子程序,用主程序调用求任意两个向量的数学叉乘值。,题目6.2设:设计一个计算S的函数子程序,并调用该函数子程序计算:题目63 设计一个计算n! 的函数子程序,并调用该子程序计算数e的近似值。当 n!1E8时停止计算。计算公式是:,题目64 对已知自然数n,设计一个判断n是否为素数的子程序,并调用该子程序:(1) 将100120共11个偶数分解为两个素数和的形式(2) 用REA

20、D语句读入一个自然数n,对n进行素因子分解。要求使用函数子程序和子例行程序两种方法。题目65 对任意自然数n,设计一个求n的各数位立方和的函数子程序F(n)(如F(121)=1*3+2*3+1*2=1+8+1=10),并调用F(n)求1000以内的所有水仙花数(水仙花数的概念请参看例 8.5)。,除了函数子程序外,还有一种子例行子程序,函数子程序和子例行子程序都是一种独立的程序单元,二者的差别是:函数子程序的名字代表一个值,因而是有类型的,而子例行程序的名字不代表一个值,因而其名字没有类型问题。从使用上来说,二者是可以相互替代的。631 子例行子程序的定义子例行子程序是由保留字SUBROUTI

21、NE开头,到保留字END结束的一个程序段。其定义格式是:SUBROUTINE 子程序名(虚参表) 子例行程序体END子程序的命名方法与变量相同。虚参由变量、数组名(不能是数组元素,常数、表达式)充当,当虚参多于一个时,各虚参间用逗号分隔,当没有虚参时,子例行程序名后的一对括弧可以省略。子例行程序的设计方法和函数子程序相同,但因为其名字没有值,所以不能有对子例行程序的名字赋值的语句。,63 子例行程序,632 子例行子程序的调用子例行程序的调用格式是:CALL 子例行程序名(实参表)其实参的类型与函数子程序相同。和函数子程序的调用不同的是,子例行子程序的调用是一个独立的语句。子例行程序调用的其它

22、事项与函数子程序的调用相同。下面通过两个实例来讨论函数子程序与子例行程序的相同点与不同点。,例 6.6 用子例行程序的方法完成例6.3分析:例6.3中定义了一个函数SM(M,N,L),我们将该函数子程序修改为一个子例行程序 SM(S,M,N,L),虚参M,N,L的含义与例8.3相同,虚参S用来存储结果和(用来替代函数名SM)。程序如下:,SUBROUTINE SM(S,M,N,L) DO I=M,N IF (L0) THEN S=S+I*L ELSE S=S+(1.0*I)*L END IF ENDDOEND,PROGRAM EXAM5 CALL SM(S1,1,100,2) CALL SM(

23、S2,100,140,3) CALL SM(S3,20,50,-1) WRITE(*,*)S1=,S1 WRITE(*,*)S2=,S2 WRITE(*,*) S3=,S3END运行结果如下: S1= 338350.000000 S2= 7.291440E+07 S3= 9.514656E-01,例 6.8 设计一个自例行程序程序,求任意矩阵的转置矩阵。设计一个子例行程序TRAN(A,B,M,N)完成将矩阵A转置后放矩阵B,M、N分别是矩阵A、B的行数和列数。主程序如下: PROGRAM EXAM6 PARAMETER(M=3) PARAMETER (N=4) DIMENSION A(M,N)

24、,B(N,M) INTEGER A,B WRITE(*,*)please input a 3x4 Matra READ(*,200)(A(I,J),J=1,N),I=1,M) CALL TRAN(A,B,M,N) WRITE(*,300)(B(I,J),J=1,M),I=1,N) 200 FORMAT(4I4) 300 FORMAT(3I5) END,子例行程序如下SUBROUTINE TRAN(A,B,M,N) INTEGER A(M,N),B(N,M),M,N DO I=1,M DO J=1,N B(J,I)=A(I,J) ENDDO ENDDOEND,运行情况:please input

25、a 3x4 Matra 1 2 3 4 5 6 7 8 9 10 11 12,显示结果如下: 1 5 9 2 6 10 3 7 11 4 8 12,优化?,641 简单变量作为虚参这是一种最常见的情况,例6.4,6.5都是这种情况,在这种情况下,根据子程序调用时实参的不同类型,又可以进一步分为两种情况:1简单变量或数组元素作为实参FUNCTION SUB(A,B) PROGRAM TTEM X=3 . Y=-5 S=S+SUB(X,Y) . END END,不同程序单元之间的数据传送方法有参数的虚实结合、建立公用区及通过数据文件等三种方式实现。本节先讨论参数的虚实结合方法,6.7节讨论公用区的

26、概念与用法,其他章节讨论文件方法。,图6.1 A、X,B、Y共用存储单元,6.4 程序单元之间的数据传递,此种情况下FORTRAN 90系统将实参与虚参安排同一个存储单元,对虚参的任何改变都作用在对应的实参上,因而调用一个子程序(包括函数子程序和子例行程序)时,实参的值有可能改变。,2常量或表达式作为实参当用常量或表达式作为实参时,FORTRAN 90编译器首先计算表达式的值(如果实参为表达式时。)然后将该值赋值给对应的虚参。此种情况下,子程序中不能改变与常量(或表达式)对应的虚参的值,否则结果难以预料。642 数组名作为虚参当虚参是数组名时,对应的实参可以是与虚参类型相同的数组名或数组元素,

27、并且实参与虚参共用一片连续的存储单元。1虚参为数值型或逻辑型数据(此时的实参当然也是对应类型)(1)实参为数组名时,FORTRAN 90 编译器将实参数组的第一个元素的存储地址传送给子程序,并将其作为对应虚参数组的第一个元素的存储地址,从而使两者共用一片存储单元。(2)当实参是一个数组元素时,FORTRAN 90 编译器将该元素的存储地址传送给子程序,并将其作为对应虚参数组的第一个元素的存储地址,从而使虚参数组与实参自该元素以后的元素共用一片存储单元。,在实参与虚参数组之间传送数据时,不要求两者的行列数相同,甚至于实参元素的个数可以多于虚参(这种情况下,多余的实参不参与子程序中的运算。)牢记:

28、FORTRAN 90是按列为主存放多维数组的,实参和虚参间的元素按存储顺序对应。如:PROGRAM TTST FUNCTION SUB2(X)DIMENSION A(3,4) DIMENSION X(2,6) DO I=1,3 S=0 DO J=1,4 DO I=1,2 A(I,J)=I+J DO J=1,6 ENDDO IF (MOD(I+J,3)=0) THEN ENDDO S=S+X(I,J) WRITE(*,*)SUB2(A) ENDIF END ENDDO,在程序TTST的倒数第二句调用了函数子程序SUB2,虚参X是一个2x6的矩阵,而实参A是一个3x4的矩阵,两者的元素对应关系是:

29、A(1,1)X(1,1),A(2,1)X(2,1),A(3,1)X(1,2)A(1,2)X(2,2),A(2,2)X(1,3),A(3,2)X(2,3)A(1,3)X(1,4),A(2,3)X(2,4),A(3,3)X(1,5) A(1,4)X(2,5),A(2,4)X(1,6),A(3,4)X(2,6) 在函数子程序SUB2中,满足求和条件的元素分别是:X(2,1),X(1,2),X(2,4),X(1,5)这些元素对应的实参元素是:A(2,1),A(3,1),A(2,3),A(3,3)故所求的函数值为:3+4+5+6=182虚参为字符型数据当虚参为字符型数据时(当然对应的实参也为字符型数据)

30、,实参和虚参不是按照数组元素的顺序对应,而是按照字符位置一一对应,读者只要了解FORTRAN 90中字符型数据的存储规则,并将实参与虚参的存储顺序派出来,就不难确定实参元素与虚参元素的对应关系,这里不再详细说明。,传递字符串变量时,可以不特别赋值它的长度。因为它的长度早就设置好了,数组会占据内存中一块连续空间,在传递参数时,实际上是传递数组元素当中某一个内存的地址。,多维数组在传递是,只有最后一维可以不赋值大小,其他所有维度必须赋值;一维数组则可以完全不用赋值维度。,3可调数组请读者重新考察例 8.8中的子例行程序TRAN(A,B,M,N),在子程序的说明中将A、B说明为A、B分别是一个M*N

31、的矩阵,注意在子程序中并没有具体规定M、N的值,这样的数组称为可调数组,可调数组的引入提高了子程序的适应性,大大提高了编程效率。应注意可调数组只能作为虚参使用,不能在主程序中使用可调数组,也不能在子程序的其它地方使用可调数组。643 子程序名作为虚参子程序的虚参不仅可以是前面所述的各种数据类型,还可以是一个子程序名。例 6.9 设有三个连续函数:,分析:用Simpson方法求函数的积分时要计算被积函数的函数值,因为三个被积函数不同,求其函数值的方法也就不同,要设计一个统一的函数子程序,必须设计一个虚参函数,并用被积函数作为实参来调用该函数子程序。用Simpson方法求函数定积分的函数子程序如下

32、:首先定义三个被积函数F(X)、G(X)、H(X)的函数子程序:FUNCTION F(X) !被积函数F(X)F=SIN(3*X)+COS(X)ENDFUNCTION G(X) !被积函数G(X)G=5*X*3+2*X-10ENDFUNCTION H(X) !被积函数H(X)H=1/(1+X*2)END,再建立 SIMPSON 求积分函数子程序FUNCTION SIMPSON(F,A,B) H=(B-A)/2C=(A+B)/2SIMPSON=H*(F(A)+4*F(C)+F(B)/3END PROGRAM SIMPSON_PRO EXTERNAL F,G,H !三个被积函数都非FORTRAN

33、90 内在函数REAL I1,I2,I3 !故定义三个函数名F、G、H为! 计算F(X)的积分 !外部函数(EXTERN 属性)I1=SIMPSON(F,0,2*3.1416)I2=SIMPSON(G,0,10.0)I3=SIMPSON(H,0,1.0)WRITE(*,*)I1=,I1WRITE(*,*)I2=,I2WRITE(*,*)I3=,I3END,程序的执行结果是: I1= -2.094445 I2= 12500.000000 I3= 7.833334E-01关于实参函数名的说明:1EXTERNAL 和 INTRINSIC调用虚参中有程序名的子程序(包括函数子程序和子例行程序)时,我们

34、要在虚参的位置代之以一个实际存在的子程序名作为实参,实参子程序如果是FORTRAN 90 的内在函数,则在调用程序段中要用保留字 INTRINSIC 对该程序名作出说明,如果实参子程序是自己设计(或调用他人的程序库)的,则必须用保留字EXTERNAL对实参程序名作出说明(如例6.9),这种对函数名属性的说明就和对变量的类型进行说明一样,说明语句必须放在该程序段的所有可执行语句前。必须强调:只需对实参的属性进行说明,至于虚参,因为其只是一个并不存在的形式子程序,并不具有INTRINSIC属性或EXTERNAL属性,是无法也无需说明其属性的。2内在函数的专用名和通用名FORTRAN 90 的内在函

35、数有通用名和专用名之分(部分函数的通用名和专用名一致),用FORTRAN 90 的内在函数作为实参时,只能使用这些函数的专用名而不能使用其通用名。,644 星号(*)作为虚参星号(*)也可以作为虚参,与星号(*)虚参对应的实参是一个冠有星号(*)的语句标号。如:PROGRAM TEST SUBROUTINE F(S,*,*) . IF (条件1)THEN . . . RETURN 1 ! return 与1之间有空格CALL F(A,*100,*200) ELSE*100 . .GOTO 300 RETURN 2*200 . ENDIF .300 END END,例 6.10 设计一个子例行程

36、序,当参数C为加号(+)时,计算并打印A+B的值,C为减号(-)时,计算并打印A-B的值。SUBROUTINE F(A,B,C,*,*,S)CHARACTER*1 C !定义参数C为单个字符变量SELECT CASE(C) CASE(+) S=A+B RETURN 1 !返回到第一个冠有 *号的语句标号 CASE(-) S=A-B RETURN 2 !返回到第二个冠有 *号的语句标号END SELECTEND,PROGRAM TESTCHARACTER*1 CWRITE(*,*)PLEASE INPUT 2 NUMBER AND A OPERATION SIGNREAD(*,*)A,B,CCA

37、LL F(A,B,C,*10,*20,S)10 WRITE(*,*)A,+,B,=,S !C参数为加号返回到此GOTO 3020 WRITE(*,*)A,-,B,=,S !C参数为减号返回到此30 END应该指出,象上面这样的分支问题,可在子程序单元F或调用程序单元TEST中用分支程序很容易地实现,这里采用的子程序中根据分支条件而返回到不同的出口的方法,违背了一个程序单元应具有单一出口的结果化原则,是不应提倡的,读者在程序设计的实践中应尽量避免这种用法。,645 变量的作用域变量是为了完成一个计算任务而设置的一些数据存储单元。FORTRAN 90为每一个变量在内存区域中建立一个物理的连续存储区

38、,一旦某个变量完成其使命,FORTRAN 90将释放该变量所占据的物理存储区,该变量变得无定义。程序设计人员不能使用已经被FORTRAN 90释放的变量。到底FORTRAN 90何时为变量建立物理的存储区,又何时释放这些存储区呢?下面就来讨论这些问题。1变量存储区的分配与释放一个程序(是一个完整的程序而非组成程序的各程序单元)在投入运行时,系统为这个程序的全部变量一次性分配存储单元,当这个程序退出运行时,系统收回这个程序所占据的全部存储单元。一个程序中的全部变量被同时建立存储单元。一般来说,一个程序的变量单元也将被同时释放,除非我们声明保留某个变量的存储单元。,2变量作用域一个变量通常只在本程

39、序单元(这里是程序单元而非整个程序)中起作用,离开建立该变量的程序单元,变量就失去了定义。这种作用域的局限性,使用户在设计程序时,只需考虑在本程序单元中的变量只否有相互干扰,而无需考虑与其它程序单元之间的变量干扰问题,简化了程序的调试工作。在程序调用时,调用程序单元的实参是通过与被调用程序单元的虚参的结合来实现的,并不是调用程序单元中的变量直接在被调用程序单元中有定义。,例 6.11 讨论变量的作用域SUBROUTINE F(A,B,C) INTEGER X,Y X=5 ! 子程序S中有X、Y Y=8 C=A+B WRITE(*,*)X、Y IN SUB,X,Y END,PROGRAM EXA

40、M8 U=5 V=8 X=3 ! 主程序中也有X、Y Y=2 CALL F(U,V,S) WRITE(*,*)X、Y IN MAIN,X,Y WRITE(*,*)U,V,S END,程序的执行结果是: X、Y IN SUB 5 8 X、Y IN MAIN 3.000000 2.000000 5.000000 8.000000 13.000000,从程序执行结果可以看到,尽管在C程序单元 EXAM8 和程序单元 VERY中都有变量X、Y,但其值是不相同的,说明它们是不相干的变量,只是同名而已。,3子程序中变量的存储属性变量有数据类型,同时还有存储属性,数据类型决定变量的运算特征,而存储属性决定一

41、个变量所占用的存储单元在什么时候被释放,FPS中,变量的几种常见的存储属性有:(1)SAVE 属性:当声明变量的子程序执行完毕后,具有SAVE属性的变量的存储状态依然保留,在下一次调用该子程序时,这些变量保持上一次调用返回时的值。(2)STATIC属性:具有该类属性的变量在整个程序(不是声明该变量的子程序)执行期中一直保留在存储单元中,这是变量的默认存储属性(3)AUTOMATIC属性:当声明变量的子程序执行完毕后,具有AUTOMATIC属性的变量的存储单元被系统回收。变量的存储属性的说明方法是:存储属性 变量名表这里的存储属性是上述三种属性之一。如:AUTOMATIC A,B,C !定义实型

42、变量A、B、C具有AUTOMATIC 存储属性INTEGER SAVE X,Y !定义变量X、Y为整型,SAVE 存储属性,例 6.12 说明变量存储属性的作用。PROGRAM DATAS_TESTDO I=1,10 WRITE(*,*)I,F()ENDDOEND,FUNCTION F()STATIC N,S ! 定义N、S为STATIC属性N=N+1S=S+NF=SEND,程序的执行结果是: 1 1.000000 2 3.000000 3 6.000000 4 10.000000 5 15.000000 6 21.000000 7 28.000000 8 36.000000 9 45.000000 10 55.000000,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 管理文献 > 管理手册

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁