第3章模块化程序设计—例程和模块

上传人:汽*** 文档编号:576737446 上传时间:2024-08-20 格式:PPT 页数:41 大小:114KB
返回 下载 相关 举报
第3章模块化程序设计—例程和模块_第1页
第1页 / 共41页
第3章模块化程序设计—例程和模块_第2页
第2页 / 共41页
第3章模块化程序设计—例程和模块_第3页
第3页 / 共41页
第3章模块化程序设计—例程和模块_第4页
第4页 / 共41页
第3章模块化程序设计—例程和模块_第5页
第5页 / 共41页
点击查看更多>>
资源描述

《第3章模块化程序设计—例程和模块》由会员分享,可在线阅读,更多相关《第3章模块化程序设计—例程和模块(41页珍藏版)》请在金锄头文库上搜索。

1、第第3章章 模块化程序设计模块化程序设计例程和模块例程和模块“模块模块”直接映射为例程:子程序和函数直接映射为例程:子程序和函数 内部例程和外部例程内部例程和外部例程 程序构造单元:主程序(包含有内部例程)程序构造单元:主程序(包含有内部例程)、模块(包含有内部例程)、外部例程、模块(包含有内部例程)、外部例程(单独的,包含有内部例程)(单独的,包含有内部例程)第一节第一节 内部例程内部例程一一 内部函数内部函数1. 1. 构造形式构造形式构造形式构造形式 实例牛顿法求解方程:方程的一般形式为实例牛顿法求解方程:方程的一般形式为实例牛顿法求解方程:方程的一般形式为实例牛顿法求解方程:方程的一般

2、形式为设根的一个近似值为设根的一个近似值为设根的一个近似值为设根的一个近似值为 , , 新的近似值新的近似值新的近似值新的近似值 为:为:为:为: 其中:其中:其中:其中: 是是是是 的一阶导数,通过叠代的方的一阶导数,通过叠代的方的一阶导数,通过叠代的方的一阶导数,通过叠代的方法获得近似解法获得近似解法获得近似解法获得近似解 ,满足,满足,满足,满足 。 假设假设 f(x)=x3+x-3, 那么那么f(x)=3x2+1;根的初值设为根的初值设为 2;叠;叠代控制条件为代控制条件为f(x)10-6 ,或者叠代步数不超过,或者叠代步数不超过20;用;用F(x)代表代表f(x),用,用DF(x)代

3、表代表f(x)。例例 3-1 3-1 牛顿法解方程牛顿法解方程 PROGRAM NewtonPROGRAM Newton IMPLICIT NONE IMPLICIT NONE INTEGER : Its =0 ! INTEGER : Its =0 !叠代数叠代数 INTEGER : MaxIts =20 !INTEGER : MaxIts =20 !最大叠代数最大叠代数 LOGICAL : Converged =.false. !LOGICAL : Converged =.false. !是否收敛是否收敛 REAL : Eps = 1e -6 !REAL : Eps = 1e -6 !叠代精

4、度叠代精度 REAL : X =2 !REAL : X =2 !根的初值根的初值 DO WHILE (.NOT. Converged .AND. ItsDO WHILE (.NOT. Converged .AND. ItsMaxItsMaxIts) ) X = XX = XF(X)/DF(X)F(X)/DF(X) PRINT*,X,F(X) PRINT*,X,F(X) Its = Its = ItsIts +1 +1 Converged = ABS(F(X)= Converged = ABS(F(X)N2N,不执行不执行不执行不执行DODO循环循环循环循环(Fact=1)(Fact=1),当函

5、数当函数当函数当函数Fact Fact 返回到主程序打印时,返回到主程序打印时,返回到主程序打印时,返回到主程序打印时,I I 的值为的值为的值为的值为2 2;下一次引用时,;下一次引用时,;下一次引用时,;下一次引用时,I I 在主程序在主程序在主程序在主程序 DO DO 循环循环循环循环中增至中增至中增至中增至3 3,依次类推,依次类推,依次类推,依次类推 正确方式是在内部函数中重新声明正确方式是在内部函数中重新声明正确方式是在内部函数中重新声明正确方式是在内部函数中重新声明 I I为局部变量。为局部变量。为局部变量。为局部变量。例如:例如:例如:例如:INTEGER IINTEGER I

6、在内部例程中声明所有变量应成为一条编程规则,在内部例程中声明所有变量应成为一条编程规则,在内部例程中声明所有变量应成为一条编程规则,在内部例程中声明所有变量应成为一条编程规则,以消除全局变量带来的负面影响。以消除全局变量带来的负面影响。以消除全局变量带来的负面影响。以消除全局变量带来的负面影响。共享数据,声明变量模块。共享数据,声明变量模块。共享数据,声明变量模块。共享数据,声明变量模块。3. 函数返回值函数返回值FortranFortran中,表达式(函数)值一是通过函数名赋值来实现,中,表达式(函数)值一是通过函数名赋值来实现,中,表达式(函数)值一是通过函数名赋值来实现,中,表达式(函数

7、)值一是通过函数名赋值来实现,例如:例如:例如:例如: F= X*3+X-3F= X*3+X-3此时赋值号左边的函数名不能带参数表。此时赋值号左边的函数名不能带参数表。此时赋值号左边的函数名不能带参数表。此时赋值号左边的函数名不能带参数表。另一是通过另一是通过另一是通过另一是通过RESULT RESULT 子句来实现,例如:子句来实现,例如:子句来实现,例如:子句来实现,例如: FUNCTION F(X) RESULT(R)FUNCTION F(X) RESULT(R) REAL R REAL R,X X R = X*3+X-3 R = X*3+X-3 END FUNCTION F END F

8、UNCTION F其中,其中,其中,其中,R R代表函数结果,其数据类型代表函数类型;赋值号代表函数结果,其数据类型代表函数类型;赋值号代表函数结果,其数据类型代表函数类型;赋值号代表函数结果,其数据类型代表函数类型;赋值号左边不再是函数名左边不再是函数名左边不再是函数名左边不再是函数名F F ,而是函数结果而是函数结果而是函数结果而是函数结果 R , R , 相应的函数类型相应的函数类型相应的函数类型相应的函数类型声明,也由声明函数名声明,也由声明函数名声明,也由声明函数名声明,也由声明函数名 F F 改为声明函数结果改为声明函数结果改为声明函数结果改为声明函数结果 R R 。 4. 语句函

9、数语句函数Fortran 90 Fortran 90 也支持也支持也支持也支持Fortran 77 Fortran 77 提供的语句函数,不推荐。提供的语句函数,不推荐。提供的语句函数,不推荐。提供的语句函数,不推荐。例例例例3-33-3语句函数的使用语句函数的使用语句函数的使用语句函数的使用 PROGRAM Statement_FunctionPROGRAM Statement_Function IMPLICIT NONE IMPLICIT NONE REAL f REAL f,x x,y !y !函数名函数名函数名函数名f f、形参形参形参形参x x、实参实参实参实参y y均需声明类型均需

10、声明类型均需声明类型均需声明类型 f(x) = x*2/SQRT(1.0 + 2.0*x + x*2) !f(x) = x*2/SQRT(1.0 + 2.0*x + x*2) !定义语句函数定义语句函数定义语句函数定义语句函数 DODO WRITE(*,(A),ADVANCE = NO) WRITE(*,(A),ADVANCE = NO) 输入输入输入输入 x x 的值:的值:的值:的值: READ*,yREAD*,y IF(INT(y) = 0) EXIT IF(INT(y) = 0) EXIT !0!0终止循环终止循环终止循环终止循环 PRINT*,f(,y,)=,f(y)PRINT*,f

11、(,y,)=,f(y) END DO END DO END PROGRAM END PROGRAM Statement_FunctionStatement_Function语句函数的形式为:语句函数的形式为: 函数名(参数函数名(参数函数名(参数函数名(参数1 1,参数,参数,参数,参数2 2,)= =函数表达式函数表达式函数表达式函数表达式 语句函数在形式上和数学上的函数表达式完全一样,语句语句函数在形式上和数学上的函数表达式完全一样,语句语句函数在形式上和数学上的函数表达式完全一样,语句语句函数在形式上和数学上的函数表达式完全一样,语句函数使用时应注意以下几点:函数使用时应注意以下几点:函

12、数使用时应注意以下几点:函数使用时应注意以下几点:(1) (1) 语句函数先定义后使用,且只能用一条语句来定义;语句函数先定义后使用,且只能用一条语句来定义;语句函数先定义后使用,且只能用一条语句来定义;语句函数先定义后使用,且只能用一条语句来定义;(2) (2) 定义语句应放在声明部分,且放在语句函数相关的类型定义语句应放在声明部分,且放在语句函数相关的类型定义语句应放在声明部分,且放在语句函数相关的类型定义语句应放在声明部分,且放在语句函数相关的类型声明之后;声明之后;声明之后;声明之后;(3) (3) 参数列表可以为空(此时,函数实际上是一常量表达式)参数列表可以为空(此时,函数实际上是

13、一常量表达式)参数列表可以为空(此时,函数实际上是一常量表达式)参数列表可以为空(此时,函数实际上是一常量表达式),但函数名后边的一对括号,无论在定义还是引用时都不,但函数名后边的一对括号,无论在定义还是引用时都不,但函数名后边的一对括号,无论在定义还是引用时都不,但函数名后边的一对括号,无论在定义还是引用时都不能省略。能省略。能省略。能省略。二二 内部子程序内部子程序内部子程序和内部函数主要差别在于:内部子程序和内部函数主要差别在于:(1 1)没有返回值和子程序名关联,因此无需声明)没有返回值和子程序名关联,因此无需声明)没有返回值和子程序名关联,因此无需声明)没有返回值和子程序名关联,因此

14、无需声明子程序类型;子程序类型;子程序类型;子程序类型;(2 2)通过)通过)通过)通过CALLCALL语句调用子程序;语句调用子程序;语句调用子程序;语句调用子程序;(3 3)在例程原型(头)和)在例程原型(头)和)在例程原型(头)和)在例程原型(头)和 END END 语句(尾)中,语句(尾)中,语句(尾)中,语句(尾)中,使用关键字使用关键字使用关键字使用关键字SUBROUTINESUBROUTINE;(4 4)若子程序参数表为空,子程序名后的一对括)若子程序参数表为空,子程序名后的一对括)若子程序参数表为空,子程序名后的一对括)若子程序参数表为空,子程序名后的一对括号可以省略;号可以省

15、略;号可以省略;号可以省略;(5 5)函数通过函数名返回一个值,子程序通过函)函数通过函数名返回一个值,子程序通过函)函数通过函数名返回一个值,子程序通过函)函数通过函数名返回一个值,子程序通过函数参数可以返回多个值。数参数可以返回多个值。数参数可以返回多个值。数参数可以返回多个值。例例例例3-4 3-4 内部子程序用来实现内部子程序用来实现内部子程序用来实现内部子程序用来实现2 2个数据的返回(交换)个数据的返回(交换)个数据的返回(交换)个数据的返回(交换) PROGRAM ExchangePROGRAM Exchange IMPLICIT NONE IMPLICIT NONE REAL

16、: A =1, B=5 REAL : A =1, B=5 CALLCALL Swop(A, B) Swop(A, B) PRINT*, A, B PRINT*, A, B CONTAINS CONTAINS SUBROUTINE Swop(X,Y)SUBROUTINE Swop(X,Y) REAL Temp, X, Y REAL Temp, X, Y Temp = X Temp = X X = Y X = Y Y = Temp Y = Temp END SUBROUTINE END SUBROUTINE END PROGRAM END PROGRAM程序说明:程序说明: Fortran For

17、tran 参数传递,缺省为引用传递参数传递,缺省为引用传递参数传递,缺省为引用传递参数传递,缺省为引用传递( (地址传递地址传递地址传递地址传递) ); 子程序调用时,实参子程序调用时,实参子程序调用时,实参子程序调用时,实参A A、B B的值被传递给参数的值被传递给参数的值被传递给参数的值被传递给参数 X X、Y Y,改变改变改变改变后的形参值被返回调用程序,实现两个数据的交换;后的形参值被返回调用程序,实现两个数据的交换;后的形参值被返回调用程序,实现两个数据的交换;后的形参值被返回调用程序,实现两个数据的交换; 子程序中的子程序中的子程序中的子程序中的Temp Temp 为局部变量,在主

18、程序中不可访问;为局部变量,在主程序中不可访问;为局部变量,在主程序中不可访问;为局部变量,在主程序中不可访问; 如果希望参数以数值方式传递,这样形参的改变不影响实如果希望参数以数值方式传递,这样形参的改变不影响实如果希望参数以数值方式传递,这样形参的改变不影响实如果希望参数以数值方式传递,这样形参的改变不影响实参,为此参,为此参,为此参,为此Fortran 90 Fortran 90 提供了提供了提供了提供了INTENT INTENT 属性。属性。属性。属性。内部子程序的构造形式:内部子程序的构造形式: SUBROUTINE SUBROUTINE 子程序名子程序名子程序名子程序名 (参数表)

19、(参数表)(参数表)(参数表) 声明语句声明语句声明语句声明语句 执行语句执行语句执行语句执行语句 END SUBROUTINE END SUBROUTINE 子程序名子程序名子程序名子程序名 主程序构造形式:主程序构造形式: PROGRAM PROGRAM 程序名程序名程序名程序名 声明语句声明语句声明语句声明语句 执行语句执行语句执行语句执行语句 CONTAINS CONTAINS 内部例程内部例程内部例程内部例程 END PROGRAM END PROGRAM 程序名程序名程序名程序名 注意事项:注意事项:(1 1)一个完整的程序有且只有一个主程序;)一个完整的程序有且只有一个主程序;)

20、一个完整的程序有且只有一个主程序;)一个完整的程序有且只有一个主程序;(2 2)主程序只有)主程序只有)主程序只有)主程序只有 END END 语句是必须的,其他都是可选的;语句是必须的,其他都是可选的;语句是必须的,其他都是可选的;语句是必须的,其他都是可选的;(3 3)若含有内部例程,必须出现关键字)若含有内部例程,必须出现关键字)若含有内部例程,必须出现关键字)若含有内部例程,必须出现关键字CONTAINSCONTAINS;(4 4)可以有多个内部例程,但内部例程不能再含有自己的内部)可以有多个内部例程,但内部例程不能再含有自己的内部)可以有多个内部例程,但内部例程不能再含有自己的内部)

21、可以有多个内部例程,但内部例程不能再含有自己的内部 例程,例程,例程,例程,不允许内部例程的嵌套不允许内部例程的嵌套不允许内部例程的嵌套不允许内部例程的嵌套;(5 5)END END 语句若出现程序名,其前面的语句若出现程序名,其前面的语句若出现程序名,其前面的语句若出现程序名,其前面的 PROGRAM PROGRAM 关键字不能少。关键字不能少。关键字不能少。关键字不能少。第二节第二节 主程序主程序构造形式:构造形式:构造形式:构造形式: SUBROUTINE SUBROUTINE 子程序名子程序名子程序名子程序名 (参数表)(参数表)(参数表)(参数表) 声明语句声明语句声明语句声明语句

22、执行语句执行语句执行语句执行语句 CONTAINS CONTAINS 内部例程内部例程内部例程内部例程 END SUBROUTINE END SUBROUTINE 子程序名子程序名子程序名子程序名 或者或者或者或者 FUNCTION FUNCTION 函数名(函数名(函数名(函数名( 参数表参数表参数表参数表 ) 声明语句声明语句声明语句声明语句 执行语句执行语句执行语句执行语句 CONTAINS CONTAINS 内部例程内部例程内部例程内部例程 END FUNCTION END FUNCTION 函数名函数名函数名函数名 外部例程和内部例程的比较:外部例程和内部例程的比较:外部例程和内部例

23、程的比较:外部例程和内部例程的比较:(1 1)外部例程是单独的外部文件,除头、尾外,形式上与主程序是相同的;)外部例程是单独的外部文件,除头、尾外,形式上与主程序是相同的;)外部例程是单独的外部文件,除头、尾外,形式上与主程序是相同的;)外部例程是单独的外部文件,除头、尾外,形式上与主程序是相同的;(2 2)外部例程可以含有内部例程,而内部例程不能再含有内部例程;)外部例程可以含有内部例程,而内部例程不能再含有内部例程;)外部例程可以含有内部例程,而内部例程不能再含有内部例程;)外部例程可以含有内部例程,而内部例程不能再含有内部例程;(3 3)ENDEND语句中的关键字语句中的关键字语句中的关

24、键字语句中的关键字 FUNCTION/ SUBROUTINEFUNCTION/ SUBROUTINE,在外部例程中是可选在外部例程中是可选在外部例程中是可选在外部例程中是可选的,但在内部例程中是必须的。的,但在内部例程中是必须的。的,但在内部例程中是必须的。的,但在内部例程中是必须的。 第三节第三节 外部例程外部例程例例例例 3-5 3-5 采用外部例程实现采用外部例程实现采用外部例程实现采用外部例程实现 SwopSwop(交换)(交换)(交换)(交换) PROGRAM ExchangePROGRAM Exchange IMPLICIT NONE IMPLICIT NONE EXTERNAL

25、Swop !EXTERNAL Swop !声明例程声明例程声明例程声明例程Swop Swop 为外部的为外部的为外部的为外部的 REAL : A =1, B=5REAL : A =1, B=5 CALL Swop(A, B) CALL Swop(A, B) PRINT*, A, B PRINT*, A, B END PROGRAM Exchange END PROGRAM Exchange SUBROUTINE Swop(X, Y) SUBROUTINE Swop(X, Y) REAL Temp, X, Y REAL Temp, X, Y Temp = X Temp = X X = Y X =

26、 Y Y = Temp Y = Temp END SUBROUTINE END SUBROUTINE SwopSwop 若外部程序名与系统的标准例程名相同,编辑器会优先引若外部程序名与系统的标准例程名相同,编辑器会优先引若外部程序名与系统的标准例程名相同,编辑器会优先引若外部程序名与系统的标准例程名相同,编辑器会优先引用标准例程,而不是用户定义的外部例程;为避免出现这用标准例程,而不是用户定义的外部例程;为避免出现这用标准例程,而不是用户定义的外部例程;为避免出现这用标准例程,而不是用户定义的外部例程;为避免出现这种情况,可在调用例程的声明部分,添加外部例程声明语种情况,可在调用例程的声明部分

27、,添加外部例程声明语种情况,可在调用例程的声明部分,添加外部例程声明语种情况,可在调用例程的声明部分,添加外部例程声明语句句句句(EXTERNAL)(EXTERNAL),这应该成为一个编程惯例。这应该成为一个编程惯例。这应该成为一个编程惯例。这应该成为一个编程惯例。 例程接口:包括例程名、参数个数及各自的数据类型等例程接口:包括例程名、参数个数及各自的数据类型等例程接口:包括例程名、参数个数及各自的数据类型等例程接口:包括例程名、参数个数及各自的数据类型等信息。分为:显式接口(对标准例程、内部例程和模块例信息。分为:显式接口(对标准例程、内部例程和模块例信息。分为:显式接口(对标准例程、内部例

28、程和模块例信息。分为:显式接口(对标准例程、内部例程和模块例程)和隐式接口(对外部例程)。程)和隐式接口(对外部例程)。程)和隐式接口(对外部例程)。程)和隐式接口(对外部例程)。 Fortran 90Fortran 90提供接口块,以向调用程序明确外部例程的提供接口块,以向调用程序明确外部例程的提供接口块,以向调用程序明确外部例程的提供接口块,以向调用程序明确外部例程的接口信息。接口信息。接口信息。接口信息。 接口块构造形式:接口块构造形式:接口块构造形式:接口块构造形式: INTERFACEINTERFACE 接口体接口体接口体接口体 END INTERFACEEND INTERFACE

29、接口体由外部例程头、参数声明和外部例程尾构成。接口体由外部例程头、参数声明和外部例程尾构成。接口体由外部例程头、参数声明和外部例程尾构成。接口体由外部例程头、参数声明和外部例程尾构成。 参数名可以和外部例程定义用的参数名不同,也可以相参数名可以和外部例程定义用的参数名不同,也可以相参数名可以和外部例程定义用的参数名不同,也可以相参数名可以和外部例程定义用的参数名不同,也可以相同(将外部例程定义的参数声明部分直接拷贝)。同(将外部例程定义的参数声明部分直接拷贝)。同(将外部例程定义的参数声明部分直接拷贝)。同(将外部例程定义的参数声明部分直接拷贝)。第四节第四节 接口块接口块例例例例3-6 3-

30、6 在主程序中添加接口块,实现在主程序中添加接口块,实现在主程序中添加接口块,实现在主程序中添加接口块,实现SwopSwop外部例程外部例程外部例程外部例程 PROGRAM ExchangePROGRAM Exchange IMPLICIT NONE IMPLICIT NONE INTERFACEINTERFACE SUBROUTINE Swop(X,Y) SUBROUTINE Swop(X,Y) REAL Temp,X,Y REAL Temp,X,Y END SUBROUTINE Swop END SUBROUTINE Swop END INTERFACE END INTERFACE REA

31、L : A =1, B=5 REAL : A =1, B=5 CALL Swop(A,B) CALL Swop(A,B) PRINT*, A , B PRINT*, A , B END PROGRAM Exchange END PROGRAM Exchange 在程序中不需要用在程序中不需要用在程序中不需要用在程序中不需要用EXTERNAL EXTERNAL 语句声明外部例程。语句声明外部例程。语句声明外部例程。语句声明外部例程。必须使用接口块的情况:必须使用接口块的情况:必须使用接口块的情况:必须使用接口块的情况:(1 1)外部例程具有可选参数;)外部例程具有可选参数;)外部例程具有可选参数

32、;)外部例程具有可选参数;(2 2)例程用来定义操作符重载;)例程用来定义操作符重载;)例程用来定义操作符重载;)例程用来定义操作符重载;(3 3)外部函数返回数组或变长字符串;)外部函数返回数组或变长字符串;)外部函数返回数组或变长字符串;)外部函数返回数组或变长字符串;(4 4)外部例程具有假定形状数组,指针或目标参数;外部例程具有假定形状数组,指针或目标参数;外部例程具有假定形状数组,指针或目标参数;外部例程具有假定形状数组,指针或目标参数;(5 5)例程作参数;)例程作参数;)例程作参数;)例程作参数;(6 6)例程重载。)例程重载。)例程重载。)例程重载。除了操作符和例程重载外,其他

33、的只要将外部例除了操作符和例程重载外,其他的只要将外部例除了操作符和例程重载外,其他的只要将外部例除了操作符和例程重载外,其他的只要将外部例程转化为模块例程,就可以免去提供接口块的麻程转化为模块例程,就可以免去提供接口块的麻程转化为模块例程,就可以免去提供接口块的麻程转化为模块例程,就可以免去提供接口块的麻烦,模块在烦,模块在烦,模块在烦,模块在Fortran 90Fortran 90中具有十分重要的作用。中具有十分重要的作用。中具有十分重要的作用。中具有十分重要的作用。1 构造形式构造形式Fortran 90 Fortran 90 有三种程序单元:主程序、外部例程有三种程序单元:主程序、外部

34、例程有三种程序单元:主程序、外部例程有三种程序单元:主程序、外部例程和模块,模块主要是用来在程序单元之间共享数和模块,模块主要是用来在程序单元之间共享数和模块,模块主要是用来在程序单元之间共享数和模块,模块主要是用来在程序单元之间共享数据和操作例程。其构造形式如下:据和操作例程。其构造形式如下:据和操作例程。其构造形式如下:据和操作例程。其构造形式如下: MODULE MODULE 模块名模块名模块名模块名 声明语句声明语句声明语句声明语句 CONTAINS CONTAINS 模块例程模块例程模块例程模块例程 END MODULE END MODULE 模块名模块名模块名模块名 第五节第五节

35、模块模块例3-7 模块使用 MODULE MyUtilsMODULE MyUtils REAL, PARAMETER : PI =3.1415927 REAL, PARAMETER : PI =3.1415927 CONTAINS CONTAINS SUBROUTINE Swop(X, Y) SUBROUTINE Swop(X, Y) REAL Temp , X , Y REAL Temp , X , Y Temp = X Temp = X X = Y X = Y Y = Temp Y = Temp END SUBROUTINE Swop END SUBROUTINE Swop END MOD

36、ULE MyUtils END MODULE MyUtils !模块和主程序在同一文件中,模块在主程序之前!模块和主程序在同一文件中,模块在主程序之前!模块和主程序在同一文件中,模块在主程序之前!模块和主程序在同一文件中,模块在主程序之前 PROGRAM MainPROGRAM Main USE MyUtils USE MyUtils ! !位于位于位于位于IMPLICIT NONEIMPLICIT NONE、声明语句之前声明语句之前声明语句之前声明语句之前 IMPLICIT NONEIMPLICIT NONE REAL : A = PI, B = PI*2 REAL : A = PI, B

37、= PI*2 CALL Swop(A, B) CALL Swop(A, B) PRINT*, A , B PRINT*, A , B END PROGRAM Main END PROGRAM Main其中:例程其中:例程其中:例程其中:例程 SwopSwop被转换为模块例程,主程序通过引用(被转换为模块例程,主程序通过引用(被转换为模块例程,主程序通过引用(被转换为模块例程,主程序通过引用(USEUSE)模块,使用)模块,使用)模块,使用)模块,使用其中的模块例程及数据。其中的模块例程及数据。其中的模块例程及数据。其中的模块例程及数据。 模块例程作为模块的内部例程,其形式和主程序,外部例模块例

38、程作为模块的内部例程,其形式和主程序,外部例模块例程作为模块的内部例程,其形式和主程序,外部例模块例程作为模块的内部例程,其形式和主程序,外部例程包含的内部例程是一样的,只不过模块例程还可以包含程包含的内部例程是一样的,只不过模块例程还可以包含程包含的内部例程是一样的,只不过模块例程还可以包含程包含的内部例程是一样的,只不过模块例程还可以包含自己的内部例程。模块、主程序、模块例程、内部例程和自己的内部例程。模块、主程序、模块例程、内部例程和自己的内部例程。模块、主程序、模块例程、内部例程和自己的内部例程。模块、主程序、模块例程、内部例程和外部例程的关系如下:外部例程的关系如下:外部例程的关系如

39、下:外部例程的关系如下: 其中其中其中其中: Mod-sub : Mod-sub 指模块例程,指模块例程,指模块例程,指模块例程,Int-subsInt-subs指内部例程,指内部例程,指内部例程,指内部例程,Ext-Ext-sub sub 指外部例程。指外部例程。指外部例程。指外部例程。ModuleMod-subInt-subsExt-subInt-subsMain programInt-subsExt-subInt-subsModule Fortran 90 Fortran 90 中,数据块程序单元被模块程序单元替代;中,数据块程序单元被模块程序单元替代;中,数据块程序单元被模块程序单元替

40、代;中,数据块程序单元被模块程序单元替代; 模块不仅可供主程序和外部例程引用,还可供其他模块引用;模块不仅可供主程序和外部例程引用,还可供其他模块引用;模块不仅可供主程序和外部例程引用,还可供其他模块引用;模块不仅可供主程序和外部例程引用,还可供其他模块引用; 主程序、模块、外部例程之间的关系如下图所示:主程序、模块、外部例程之间的关系如下图所示:主程序、模块、外部例程之间的关系如下图所示:主程序、模块、外部例程之间的关系如下图所示:Program A1Use module AModule AContainsModule subroutine of funotionSubroutine BEx

41、ternalsubroutineCall BContainsEnd Program A1Internal subroutineof funotion主程序、模块、外部例程之间的关系2 USE语句语句 模块的引用,一般形式为:模块的引用,一般形式为:模块的引用,一般形式为:模块的引用,一般形式为: USE USE 模块名模块名 模块的引用,其他形式为:模块的引用,其他形式为:模块的引用,其他形式为:模块的引用,其他形式为:(1 1)不方便直接使用模块实体名,可在程序中重新命名,引用形式为:)不方便直接使用模块实体名,可在程序中重新命名,引用形式为:)不方便直接使用模块实体名,可在程序中重新命名,

42、引用形式为:)不方便直接使用模块实体名,可在程序中重新命名,引用形式为: USE USE 模块名,重命名列表(新实体名模块名,重命名列表(新实体名模块名,重命名列表(新实体名模块名,重命名列表(新实体名 = =原实体名)原实体名)原实体名)原实体名) 例如:模块例如:模块例如:模块例如:模块YourModYourMod有一个例程或者变量有一个例程或者变量有一个例程或者变量有一个例程或者变量YourPlonkYourPlonk,被重新命名为,被重新命名为,被重新命名为,被重新命名为MyPlonkMyPlonk: USE USE YourModYourMod, , MyPlonkMyPlonk =

43、 =YourPlonkYourPlonk(2 2)程序只使用模块中的部分实体,采用如下的引用形式:)程序只使用模块中的部分实体,采用如下的引用形式:)程序只使用模块中的部分实体,采用如下的引用形式:)程序只使用模块中的部分实体,采用如下的引用形式: USE YourModUSE YourMod,ONLY ONLY :X X,Y Y 这表示只使用模块这表示只使用模块这表示只使用模块这表示只使用模块 YourMod YourMod 中的中的中的中的 X X 和和和和 Y Y,冒号后边的实体可被重命名。,冒号后边的实体可被重命名。,冒号后边的实体可被重命名。,冒号后边的实体可被重命名。(3 3)假如

44、要同时引用多个模块,每个模块都要使用单独的)假如要同时引用多个模块,每个模块都要使用单独的)假如要同时引用多个模块,每个模块都要使用单独的)假如要同时引用多个模块,每个模块都要使用单独的 USEUSE语句,并使语句,并使语句,并使语句,并使 USEUSE 语句出现在语句出现在语句出现在语句出现在 IMPLICIT NONE IMPLICIT NONE 之前,模块的先后次序无关紧要。之前,模块的先后次序无关紧要。之前,模块的先后次序无关紧要。之前,模块的先后次序无关紧要。3 PUBLIC 和和 PRIVATE 属性属性信息隐蔽:信息隐蔽:信息隐蔽:信息隐蔽: PRIVATEPRIVATE,将模块

45、内部使用的实体隐藏,将模块内部使用的实体隐藏,将模块内部使用的实体隐藏,将模块内部使用的实体隐藏,实体访问只限于模块内;实体访问只限于模块内;实体访问只限于模块内;实体访问只限于模块内;缺省访问属性:缺省访问属性:缺省访问属性:缺省访问属性: PUBLICPUBLIC,外部程序只使用公共部,外部程序只使用公共部,外部程序只使用公共部,外部程序只使用公共部分的实体。例如:分的实体。例如:分的实体。例如:分的实体。例如: REALREAL,PRIVATE : XPRIVATE : X将实型变量将实型变量将实型变量将实型变量 X X 规定为私有的,只能在模块内访问。规定为私有的,只能在模块内访问。规

46、定为私有的,只能在模块内访问。规定为私有的,只能在模块内访问。 PRIVATE XPRIVATE X,SwopSwop 同时规定变量同时规定变量同时规定变量同时规定变量 X X,例程例程例程例程Swop Swop 为私有的。为私有的。为私有的。为私有的。 PRIVATEPRIVATE PUBLIC PUBLIC SwopSwop不带实体列表,除不带实体列表,除不带实体列表,除不带实体列表,除SwopSwop外,其余的模块实体都是私有的。外,其余的模块实体都是私有的。外,其余的模块实体都是私有的。外,其余的模块实体都是私有的。第六节第六节 例程参数例程参数形参(虚参):相对于实参而言形参(虚参)

47、:相对于实参而言形参(虚参):相对于实参而言形参(虚参):相对于实参而言例程在定义时,列表中的参数只是特定数据类型的占位符,例程在定义时,列表中的参数只是特定数据类型的占位符,例程在定义时,列表中的参数只是特定数据类型的占位符,例程在定义时,列表中的参数只是特定数据类型的占位符,系统不会为他们分配存储单元,称为形参或者虚参;系统不会为他们分配存储单元,称为形参或者虚参;系统不会为他们分配存储单元,称为形参或者虚参;系统不会为他们分配存储单元,称为形参或者虚参;例程被调用或引用时,列表中的参数被分配一定的存储单例程被调用或引用时,列表中的参数被分配一定的存储单例程被调用或引用时,列表中的参数被分

48、配一定的存储单例程被调用或引用时,列表中的参数被分配一定的存储单元,并接收外部实参传递进来的值;元,并接收外部实参传递进来的值;元,并接收外部实参传递进来的值;元,并接收外部实参传递进来的值;例程执行完毕,例程中的参数所占有的存储空间被系统自动例程执行完毕,例程中的参数所占有的存储空间被系统自动例程执行完毕,例程中的参数所占有的存储空间被系统自动例程执行完毕,例程中的参数所占有的存储空间被系统自动释放,空间中保存的参数值也随之消失。释放,空间中保存的参数值也随之消失。释放,空间中保存的参数值也随之消失。释放,空间中保存的参数值也随之消失。 例程中的局部变量具有同样的性质:例程中的局部变量具有同

49、样的性质:例程中的局部变量具有同样的性质:例程中的局部变量具有同样的性质:例程执行时例程执行时例程执行时例程执行时“ “生存生存生存生存” ”,例程不执行时,例程不执行时,例程不执行时,例程不执行时“ “消亡消亡消亡消亡” ”;如果声明变量具有如果声明变量具有如果声明变量具有如果声明变量具有SAVE SAVE 属性,局部变量就是静态变量,属性,局部变量就是静态变量,属性,局部变量就是静态变量,属性,局部变量就是静态变量,从例程中被调用到程序结束,一直保存有特定的值。从例程中被调用到程序结束,一直保存有特定的值。从例程中被调用到程序结束,一直保存有特定的值。从例程中被调用到程序结束,一直保存有特

50、定的值。1 1 参数传递参数传递参数传递参数传递 实参和虚参之间的数据传递实参和虚参之间的数据传递实参和虚参之间的数据传递实参和虚参之间的数据传递(1 1)引用传递;(引用传递;(引用传递;(引用传递;(2 2)值传递。)值传递。)值传递。)值传递。 Fortran Fortran 中参数(包括数组参数)通常是以中参数(包括数组参数)通常是以中参数(包括数组参数)通常是以中参数(包括数组参数)通常是以引用方式引用方式引用方式引用方式传递,即地址传递;传递,即地址传递;传递,即地址传递;传递,即地址传递; 在实参为常量和表达式的情况下,参数是以在实参为常量和表达式的情况下,参数是以在实参为常量和

51、表达式的情况下,参数是以在实参为常量和表达式的情况下,参数是以值方式值方式值方式值方式传递;传递;传递;传递; 若将变量实参括起来,该实参被转化为表达式,表达式以若将变量实参括起来,该实参被转化为表达式,表达式以若将变量实参括起来,该实参被转化为表达式,表达式以若将变量实参括起来,该实参被转化为表达式,表达式以值方式值方式值方式值方式传递。传递。传递。传递。例如:例如:例如:例如: CALL SubCALL Sub(A A),),),),B B) 其中,(其中,(其中,(其中,(A A)是表达式,以值方式传递。)是表达式,以值方式传递。)是表达式,以值方式传递。)是表达式,以值方式传递。* *

52、 引用传递就是将实参的内存地址传递给虚参,例程中虚参的变化会反映到实参中;引用传递就是将实参的内存地址传递给虚参,例程中虚参的变化会反映到实参中;引用传递就是将实参的内存地址传递给虚参,例程中虚参的变化会反映到实参中;引用传递就是将实参的内存地址传递给虚参,例程中虚参的变化会反映到实参中;值传递就是将实参值的拷贝传递给虚参,虚参的变化不会影响实参。值传递就是将实参值的拷贝传递给虚参,虚参的变化不会影响实参。值传递就是将实参值的拷贝传递给虚参,虚参的变化不会影响实参。值传递就是将实参值的拷贝传递给虚参,虚参的变化不会影响实参。* 为确保参数按用户的意愿进行传递,为确保参数按用户的意愿进行传递,为

53、确保参数按用户的意愿进行传递,为确保参数按用户的意愿进行传递,Fortran 90Fortran 90提供了提供了提供了提供了INTENT INTENT 属性,例如:属性,例如:属性,例如:属性,例如: SUBROUTINE SUB SUBROUTINE SUB (X X,Y Y,Z Z) REALREAL,INTENTINTENT(ININ) : X : X ! ! 向例程传入数据,拥有该属性的虚参不允许改变向例程传入数据,拥有该属性的虚参不允许改变向例程传入数据,拥有该属性的虚参不允许改变向例程传入数据,拥有该属性的虚参不允许改变 REALREAL,INTENTINTENT(OUTOUT)

54、 : Y : Y ! ! 向例程传出数据,对应的实参必须是一变量向例程传出数据,对应的实参必须是一变量向例程传出数据,对应的实参必须是一变量向例程传出数据,对应的实参必须是一变量 REALREAL,INTENTINTENT(INOUTINOUT) : Z : Z ! ! 传出传出传出传出/ /传进数据,对应的实参必须是一个变量传进数据,对应的实参必须是一个变量传进数据,对应的实参必须是一个变量传进数据,对应的实参必须是一个变量 END SUBROUTINE SUB END SUBROUTINE SUB2 2 参数类型匹配参数类型匹配参数类型匹配参数类型匹配 PROGRAM MainPROGRA

55、M Main IMPLICIT NONE IMPLICIT NONE EXTERNAL Sub EXTERNAL Sub INTEGER : X=1 INTEGER : X=1 !对应实参!对应实参!对应实参!对应实参X X声明为整型声明为整型声明为整型声明为整型 CALL Sub(X)CALL Sub(X) PRINT PRINT* * * * , X=X=,X X END PROGRAM END PROGRAM SUBROUTINE Sub SUBROUTINE Sub(A A) IMPLICIT NONEIMPLICIT NONE REAL REAL,INTENTINTENT(INOUT

56、INOUT): A : A !虚参!虚参!虚参!虚参A A声明实型,对应实参为声明实型,对应实参为声明实型,对应实参为声明实型,对应实参为X X A=A+1 A=A+1 END SUBROUTINE END SUBROUTINE 例例例例3-83-8中,参数类型不匹配,出错!中,参数类型不匹配,出错!中,参数类型不匹配,出错!中,参数类型不匹配,出错!3 可选参数可选参数 参数列表可以很长,但并不是所有的参数都需要传递,这种参数列表可以很长,但并不是所有的参数都需要传递,这种参数列表可以很长,但并不是所有的参数都需要传递,这种参数列表可以很长,但并不是所有的参数都需要传递,这种情况下,可以规定

57、部分或全部参数具有可选(情况下,可以规定部分或全部参数具有可选(情况下,可以规定部分或全部参数具有可选(情况下,可以规定部分或全部参数具有可选(OPTIONALOPTIONAL)属)属)属)属性。性。性。性。 假如参数列表既有必选参数又有可选参数,那么所有的必选假如参数列表既有必选参数又有可选参数,那么所有的必选假如参数列表既有必选参数又有可选参数,那么所有的必选假如参数列表既有必选参数又有可选参数,那么所有的必选参数必须放在可选参数之前,先必选,后可选。参数必须放在可选参数之前,先必选,后可选。参数必须放在可选参数之前,先必选,后可选。参数必须放在可选参数之前,先必选,后可选。 例如一个外部

58、例程例如一个外部例程例如一个外部例程例如一个外部例程Sub Sub 有有有有6 6个参数,个参数,个参数,个参数,2 2个必选,个必选,个必选,个必选,4 4个是可选,调个是可选,调个是可选,调个是可选,调用程序中的接口块形式如下:用程序中的接口块形式如下:用程序中的接口块形式如下:用程序中的接口块形式如下: INTERFACEINTERFACE SUBROUTINE Sub( DumU,DumV,DumW,DumX,DumY,DumZ ) SUBROUTINE Sub( DumU,DumV,DumW,DumX,DumY,DumZ ) REAL DumU,DumV,DumW,DumX,DumY

59、,DumZ REAL DumU,DumV,DumW,DumX,DumY,DumZ OPTIONAL DumW,DumX,DumY,DumZ OPTIONAL DumW,DumX,DumY,DumZ END SUBROUTINE END SUBROUTINE END INTERFACE END INTERFACE调用语句 CALL SubCALL Sub(A A,B B) !1 1 CALL Sub CALL Sub(A A,B B,C C,D D) !2 2 CALL Sub CALL Sub(A A,B B,DumX=DDumX=D,DumY=EDumY=E,DumZ=FDumZ=F) !3

60、 3对!对!对!对!1 1,只有必选参数,只有必选参数,只有必选参数,只有必选参数DumUDumU,DumVDumV被传递;被传递;被传递;被传递;对!对!对!对!2 2,2 2个必选参数个必选参数个必选参数个必选参数DumUDumU,DumVDumV 和前面的和前面的和前面的和前面的2 2个可选参数个可选参数个可选参数个可选参数DumWDumW,DumXDumX被传递;被传递;被传递;被传递;对!对!对!对!3 3,2 2个必选参数个必选参数个必选参数个必选参数DumUDumU,DumVDumV和后边的和后边的和后边的和后边的3 3个可选参数个可选参数个可选参数个可选参数DumXDumX,D

61、umYDumY,DumZDumZ被传递。被传递。被传递。被传递。对对对对!1 1,!,!,!,!2 2,没有特别说明,参数传递按照列表顺序;,没有特别说明,参数传递按照列表顺序;,没有特别说明,参数传递按照列表顺序;,没有特别说明,参数传递按照列表顺序;对对对对!3 3,可选参数可以不按声明的列表次序进行调用;若不按列表次序调可选参数可以不按声明的列表次序进行调用;若不按列表次序调可选参数可以不按声明的列表次序进行调用;若不按列表次序调可选参数可以不按声明的列表次序进行调用;若不按列表次序调用,可选的虚参名必须被引用(需要提供关键字参数列表)。一旦某用,可选的虚参名必须被引用(需要提供关键字参

62、数列表)。一旦某用,可选的虚参名必须被引用(需要提供关键字参数列表)。一旦某用,可选的虚参名必须被引用(需要提供关键字参数列表)。一旦某个可选参数使用了关键字,其后面的可选参数都使用关键字。例如:个可选参数使用了关键字,其后面的可选参数都使用关键字。例如:个可选参数使用了关键字,其后面的可选参数都使用关键字。例如:个可选参数使用了关键字,其后面的可选参数都使用关键字。例如: CALL SubCALL Sub(A A,B B,DumX=DDumX=D,E E,F F)是错误的)是错误的)是错误的)是错误的外部例程使用可选参数,需要在调用程序中建立其接口块。外部例程使用可选参数,需要在调用程序中建

63、立其接口块。外部例程使用可选参数,需要在调用程序中建立其接口块。外部例程使用可选参数,需要在调用程序中建立其接口块。例例例例3-9 3-9 可选参数的使用可选参数的使用可选参数的使用可选参数的使用 MODULE ModMODULE Mod IMPLICIT NONE IMPLICIT NONE CONTAINS CONTAINS REAL FUNCTION Func(X,A,B,C) REAL FUNCTION Func(X,A,B,C) ! ! 计算计算计算计算FUNC(X)=AFUNC(X)=A* * * *X2+BX2+B* * * *X+CX+C ! A,B,C ! A,B,C 不传入

64、,值为不传入,值为不传入,值为不传入,值为 0 0 REAL, INTENT(IN) : X ! X REAL, INTENT(IN) : X ! X值一定要传入值一定要传入值一定要传入值一定要传入 REAL,OPTIONAL,INTENT(IN) : A,B,C ! A,B,CREAL,OPTIONAL,INTENT(IN) : A,B,C ! A,B,C可以不传入可以不传入可以不传入可以不传入 REAL RA, RB, RCREAL RA, RB, RC RA=0.0;RB=0.0;RC=0.0 ! RA=0.0;RB=0.0;RC=0.0 ! 几个简单的赋值语句放在一几个简单的赋值语句放

65、在一几个简单的赋值语句放在一几个简单的赋值语句放在一行行行行 IF ( PRESENT(A) ) RA = A ! IF ( PRESENT(A) ) RA = A ! 检查可选参数是否存在检查可选参数是否存在检查可选参数是否存在检查可选参数是否存在 IF ( PRESENT(B) ) RB = BIF ( PRESENT(B) ) RB = B IF ( PRESENT(C) ) RC = C IF ( PRESENT(C) ) RC = C Func = RA Func = RA* * * *X X*2 + RB2 + RB* * * *X + RCX + RC END FUNCTION

66、END FUNCTION END MODULE END MODULE PROGRAM Main PROGRAM Main USE Mod USE Mod IMPLICIT NONE IMPLICIT NONE PRINT PRINT* * * *, Func(2.0, C=1.0) ! F(2)=0, Func(2.0, C=1.0) ! F(2)=0* * * *22+022+0* * * *2+1 = 12+1 = 1 PRINT PRINT* * * *, Func(2.0, B=1.0, A=2.0) ! F(2)=2, Func(2.0, B=1.0, A=2.0) ! F(2)=2

67、* * * *22+122+1* * * *2+0 = 102+0 = 10 END PROGRAM END PROGRAM例程重载:例程重载:例程重载:例程重载:指不同参数列表的例程被赋予相同的名指不同参数列表的例程被赋予相同的名指不同参数列表的例程被赋予相同的名指不同参数列表的例程被赋予相同的名字,例程调用时,编译器会依据所传递的实参类字,例程调用时,编译器会依据所传递的实参类字,例程调用时,编译器会依据所传递的实参类字,例程调用时,编译器会依据所传递的实参类型,按实参和虚参类型匹配的原则,调用或引用型,按实参和虚参类型匹配的原则,调用或引用型,按实参和虚参类型匹配的原则,调用或引用型,按

68、实参和虚参类型匹配的原则,调用或引用相关的例程。例如子程序相关的例程。例如子程序相关的例程。例如子程序相关的例程。例如子程序 SwopSwop(X X,Y Y),其功),其功),其功),其功能是交换能是交换能是交换能是交换2 2个数的值。其中的个数的值。其中的个数的值。其中的个数的值。其中的2 2个参数,可以是实个参数,可以是实个参数,可以是实个参数,可以是实数,也可以是整数。数,也可以是整数。数,也可以是整数。数,也可以是整数。例例例例3-103-10 MODULE ModMODULE Mod IMPLICIT NONE IMPLICIT NONE INTERFACE INTERFACE S

69、wopSwop ! !SwopSwop 是调用时使用的例程名是调用时使用的例程名是调用时使用的例程名是调用时使用的例程名 MODULE PROCEDURE MODULE PROCEDURE SwopRealSwopReal, , SwopIntegersSwopIntegers END INTERFACE END INTERFACE 第七节第七节 例程重载例程重载!实型数据交换实型数据交换实型数据交换实型数据交换 CONTAINSCONTAINS SUBROUTINE SwopReals(X,Y) SUBROUTINE SwopReals(X,Y) REAL, INTENT(INOUT) :

70、X,Y REAL, INTENT(INOUT) : X,Y REAL Temp REAL Temp Temp = X Temp = X X = Y X = Y Y = Temp Y = Temp END SUBROUTINE END SUBROUTINE!整型数据交换!整型数据交换!整型数据交换!整型数据交换 SUBROUTINE SwopIntegers(X,Y)SUBROUTINE SwopIntegers(X,Y) INTEGER, INTENT(INOUT) : X, Y INTEGER, INTENT(INOUT) : X, Y INTEGER, Temp INTEGER, Temp

71、 Temp = X Temp = X X = Y X = Y Y = Temp Y = Temp END SUBROUTINE END SUBROUTINE END MODULE END MODULE!主程序!主程序!主程序!主程序 PROGRAM MainPROGRAM Main USE Mod USE Mod IMPLICIT NONE IMPLICIT NONE REAL : A=1.0, B=2.0 REAL : A=1.0, B=2.0 INTEGER : I=1,J=2 INTEGER : I=1,J=2 CALL CALL Swop(ASwop(A, B), B) CALL CA

72、LL Swop(ISwop(I, J), J) PRINT PRINT* * * *,A=,A,B=,B,A=,A,B=,B PRINT PRINT* * * *,I=,I,J=,J,I=,I,J=,J END PROGRAM END PROGRAM 建立重载例程接口块,以调用的例程名命名接口块:建立重载例程接口块,以调用的例程名命名接口块:建立重载例程接口块,以调用的例程名命名接口块:建立重载例程接口块,以调用的例程名命名接口块: INTERFACE SwopINTERFACE Swop MODULE PROCEDURE SwopReals MODULE PROCEDURE SwopReal

73、s,SwopIntegersSwopIntegers END INTERFACE END INTERFACE 体的例程作为外部例程,调用程序过程中建立的接口块为:体的例程作为外部例程,调用程序过程中建立的接口块为:体的例程作为外部例程,调用程序过程中建立的接口块为:体的例程作为外部例程,调用程序过程中建立的接口块为: INTERFACE INTERFACE SwopSwop !相比一般的例程接口块,多了接口名!相比一般的例程接口块,多了接口名!相比一般的例程接口块,多了接口名!相比一般的例程接口块,多了接口名SwopSwop SUBROUTINE SwopReals SUBROUTINE Sw

74、opReals(X X,Y Y) REALREAL,INTENTINTENT(INOUTINOUT) : X: X,Y Y END SUBROUTINE END SUBROUTINE SUBROUTINE SUBROUTINE SwopIntegersSwopIntegers(X X,Y Y) INTEGERINTEGER,INTENTINTENT(INOUTINOUT) : X: X,Y Y END SUBROUTINE END SUBROUTINE END INTERFACE END INTERFACE递归例程递归例程:在一个例程体内出现直接或间接:在一个例程体内出现直接或间接调用例程自身

75、的语句,称该例程为递归例调用例程自身的语句,称该例程为递归例程。递归例程的典型例子是计算程。递归例程的典型例子是计算n!Fortran 90 Fortran 90 支持递归,但必须添加支持递归,但必须添加支持递归,但必须添加支持递归,但必须添加RECURSIVE RECURSIVE 关键字,在例程是函数的情况下,还须添加关键字,在例程是函数的情况下,还须添加关键字,在例程是函数的情况下,还须添加关键字,在例程是函数的情况下,还须添加RESULT RESULT 子句;子句;子句;子句;在递归函数体内引用函数自身时,用的是函数名在递归函数体内引用函数自身时,用的是函数名在递归函数体内引用函数自身时

76、,用的是函数名在递归函数体内引用函数自身时,用的是函数名(Factorial)(Factorial),赋值给函数时,用的是结果名,赋值给函数时,用的是结果名,赋值给函数时,用的是结果名,赋值给函数时,用的是结果名(Fact) (Fact) 。第八节第八节 递归例程递归例程例例例例3-11 3-11 递归函数求递归函数求递归函数求递归函数求n!n! PROGRAM MainPROGRAM Main IMPLICIT NONE IMPLICIT NONE INTEGER I INTEGER I DO I=1, 10 DO I=1, 10 PRINT*,I,!=, PRINT*,I,!=, Fact

77、orial(IFactorial(I) ) END DO END DO CONTAINS CONTAINS RECURSIVE FUNCTION Factorial(N) RESULT(Fact) RECURSIVE FUNCTION Factorial(N) RESULT(Fact) INTEGER Fact, N INTEGER Fact, N IF(N = 1)THEN IF(N = 1)THEN Fact = 1 Fact = 1 ELSE ELSE Fact = N * Factorial( N-1 ) Fact = N * Factorial( N-1 ) !引用的是函数名!引用的

78、是函数名!引用的是函数名!引用的是函数名FactorialFactorial !赋值采用的是!赋值采用的是!赋值采用的是!赋值采用的是FactFact END IF END IF END FUCTION END FUCTION END PROGRAM END PROGRAM 递归算法简单直观,容易编写程序,但递归算法执行效率递归算法简单直观,容易编写程序,但递归算法执行效率递归算法简单直观,容易编写程序,但递归算法执行效率递归算法简单直观,容易编写程序,但递归算法执行效率低,原因是递归包含低,原因是递归包含低,原因是递归包含低,原因是递归包含递推和回归递推和回归递推和回归递推和回归2 2 2

79、2个过程,系统分别要进个过程,系统分别要进个过程,系统分别要进个过程,系统分别要进行进栈和出栈操作。例如求行进栈和出栈操作。例如求行进栈和出栈操作。例如求行进栈和出栈操作。例如求5!5!5!5!,递推过程:递推过程:递推过程:递推过程: 5! = 55! = 55! = 55! = 54!4!4!4! 4! = 4 4! = 4 4! = 4 4! = 43!3!3!3! 3! = 3 3! = 3 3! = 3 3! = 32!2!2!2! 2! = 2 2! = 2 2! = 2 2! = 21!1!1!1! 1! = 1 1! = 1 1! = 1 1! = 1回归过程:回归过程:回归过

80、程:回归过程: 2! = 22! = 22! = 22! = 21! = 21! = 21! = 21! = 2 3! = 3 3! = 3 3! = 3 3! = 32! = 62! = 62! = 62! = 6 4! = 4 4! = 4 4! = 4 4! = 43! = 243! = 243! = 243! = 24 5! = 5 5! = 5 5! = 5 5! = 54! = 1204! = 1204! = 1204! = 120 所以递归程序设计除了要找出递归表达式外,还要确定递所以递归程序设计除了要找出递归表达式外,还要确定递所以递归程序设计除了要找出递归表达式外,还要确定递

81、所以递归程序设计除了要找出递归表达式外,还要确定递归的终止条件(如:归的终止条件(如:归的终止条件(如:归的终止条件(如:1 1 1 1!=1=1=1=1),无限递归没有任何意义;),无限递归没有任何意义;),无限递归没有任何意义;),无限递归没有任何意义;在递归子程序下,同样须添加在递归子程序下,同样须添加在递归子程序下,同样须添加在递归子程序下,同样须添加RECURSIVE RECURSIVE RECURSIVE RECURSIVE 关键字。关键字。关键字。关键字。 PROGRAM MainPROGRAM Main IMPLICIT NONE IMPLICIT NONE INTEGER F

82、, I INTEGER F, I DO I = 1, 10 DO I = 1, 10 CALL Factorial( F, I ) CALL Factorial( F, I ) PRINT PRINT* * * *,I,!,F,I,!,F END DO END DO CONTAINS CONTAINS RECURSIVE SUBROUTINE Factorial( F, N ) RECURSIVE SUBROUTINE Factorial( F, N ) INTEGER F, N INTEGER F, N IF (N = 1) THEN IF (N = 1) THEN F = 1 F = 1

83、ELSE ELSE CALL Factorial( F,N-1) CALL Factorial( F,N-1) F = N F = N * * * * F F !该递归子程序的关键,将赋值语句!该递归子程序的关键,将赋值语句!该递归子程序的关键,将赋值语句!该递归子程序的关键,将赋值语句 F = N F = N * * * * F F 置于递归调用语句之后置于递归调用语句之后置于递归调用语句之后置于递归调用语句之后 END IFEND IF END SUBROUTINE END SUBROUTINE END PROGRAM END PROGRAM小小 结结(1)模块化程序的设计思想:将大的程序

84、分解为若干个功能单一的模块化程序的设计思想:将大的程序分解为若干个功能单一的例程。例程可以是包含在程序单元中的内部例程,也可是作为独立例程。例程可以是包含在程序单元中的内部例程,也可是作为独立程序单元使用的外部例程。程序单元使用的外部例程。Fortran90程序单元包括主程序、外部例程序单元包括主程序、外部例程和模块。其中,主程序和外部例程包含的内部例程不能再包含内程和模块。其中,主程序和外部例程包含的内部例程不能再包含内部例程,而模块中的模块例程允许包含其内部例程,即例程嵌套。部例程,而模块中的模块例程允许包含其内部例程,即例程嵌套。(2)若外部接口信息较简单,可以通过)若外部接口信息较简单

85、,可以通过EXTERNAL关键字将例程关键字将例程声明为外部的,以防止调用程序使用和外部例程同名的标准例程;声明为外部的,以防止调用程序使用和外部例程同名的标准例程;若外部接口信息复杂或某些特殊情况下,必须建立接口块,使编译若外部接口信息复杂或某些特殊情况下,必须建立接口块,使编译器可以产生正确的调用。编译器自动为标准例程、内部例程和模块器可以产生正确的调用。编译器自动为标准例程、内部例程和模块例程提供显式接口。例程提供显式接口。(3)模块通常含有全局变量和通用例程,专供其他程序单元使用。)模块通常含有全局变量和通用例程,专供其他程序单元使用。在通过在通过USE语句引用模块时,可只使用其中的部

86、分实体,还可为模语句引用模块时,可只使用其中的部分实体,还可为模块实体重命名。模块中实体的缺省访问属性为块实体重命名。模块中实体的缺省访问属性为PUBLIC,PRIVATE属性则将实体访问属性限定在模块内。属性则将实体访问属性限定在模块内。(4)实参和虚参间的数据传递必须类型匹配。实参变量实参和虚参间的数据传递必须类型匹配。实参变量以引用方式传递,常量和表达式则以值方式传递,编程以引用方式传递,常量和表达式则以值方式传递,编程中应通过中应通过INTENT属性明确规定参数的传递方式。属性明确规定参数的传递方式。Fortran 90 允许声明可选参数,允许以关键字形式使用可允许声明可选参数,允许以

87、关键字形式使用可选参数。选参数。 具有可选参数的外部例程,使用时需在调用程具有可选参数的外部例程,使用时需在调用程序中建立其接口块。序中建立其接口块。(5)重载例程通过有名接口块来规定,重载的具体例程)重载例程通过有名接口块来规定,重载的具体例程可以是模块例程,也可以是可以是模块例程,也可以是 外部例程,但要求规定不同外部例程,但要求规定不同的接口体。的接口体。(6) Fortran 90支持递归,允许例程直接或间接调用自支持递归,允许例程直接或间接调用自身。但前提是声明例程时要添加身。但前提是声明例程时要添加RECURSIVE 关键字,关键字,在函数例程情况下,还要添加在函数例程情况下,还要添加RESULT子句。子句。

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 幼儿/小学教育 > 幼儿教育

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号