Fortran程序设计第12章程序的单位文档格式.docx

上传人:b****7 文档编号:22616928 上传时间:2023-02-04 格式:DOCX 页数:32 大小:100.54KB
下载 相关 举报
Fortran程序设计第12章程序的单位文档格式.docx_第1页
第1页 / 共32页
Fortran程序设计第12章程序的单位文档格式.docx_第2页
第2页 / 共32页
Fortran程序设计第12章程序的单位文档格式.docx_第3页
第3页 / 共32页
Fortran程序设计第12章程序的单位文档格式.docx_第4页
第4页 / 共32页
Fortran程序设计第12章程序的单位文档格式.docx_第5页
第5页 / 共32页
点击查看更多>>
下载资源
资源描述

Fortran程序设计第12章程序的单位文档格式.docx

《Fortran程序设计第12章程序的单位文档格式.docx》由会员分享,可在线阅读,更多相关《Fortran程序设计第12章程序的单位文档格式.docx(32页珍藏版)》请在冰豆网上搜索。

Fortran程序设计第12章程序的单位文档格式.docx

程序单位

FORTRAN的程序单位分为两大类:

● 

可执行程序单位;

不可执行程序单位。

其中可执行程序单位,用来执行一个完整的功能,包括:

主程序;

外部函数子程序;

外部子例行程序子程序。

不可执行程序单位,用来为其他程序单位提供定义,包括:

模块程序单位;

数据块程序单位。

因此上面的五种类型的程序单位构成了FORTRAN程序的基本单位,不过在后面我们会看到,数据块程序单位属于早期版本的遗留物,完全是多余的。

一个完整的FORTRAN程序至少需要一个主程序,而且也只能有一个主程序。

一般说来,要完成一个完整的计算任务,除了一个主程序之外,往往还需要有函数以及子例行程序作为辅助,这时,主程序的作用就还包括驱动与管理这些作为过程的外部子程序,使得它们构成一个整体,从而完整地解决相关计算问题。

模块程序单位主要是提供给编程者用来组织程序元素的。

一个模块程序单位包含了如下几个方面的内容:

数据声明;

派生类型定义;

过程界面信息;

供其他程序单位使用的子程序定义。

因此这样一个程序单位本身不是可执行程序单位。

数据块程序单位用于给出命名公用块里面的变量的初始值,因此同样不是可执行程序单位。

由于FORTRAN的现代版本引入了模块结构,而模块能够提供全局的数据初始化,因此数据块程序单位几乎可以说是多余的。

由于在第13章我们将专门讨论过程以及过程的应用,因此属于过程的外部函数子程序和外部子例行程序子程序,在本章都只是简略说明,需要详细讨论的是主程序和模块。

各种程序单位里面并不是能够使用任何FORTRAN语句,语句类型与程序单位之间的兼容性在下面的表中予以说明。

表12-1 

语句与程序单元的兼容性

语 

主程序

模块说明部分

数据块

外部子程序

模块子程序

内部子程序

界面体

USE语句

ENTRY语句

FORMAT语句

几种声明语句*

DATA语句

派生类型定义

界面块

语句函数#

CONTAINS

可执行语句

注意:

*几种声明语句包括:

PARAMETER语句,IMPLICIT语句,类型声明语句以及说明语句。

#语句函数语句属于过时语言成分。

一个FORTRAN程序总是从主程序的第一个可执行语句开始运行,在第三章我们已经讨论过一个完整FORTRAN程序的结构。

在下面的图12-1中,我们再给出一个完整FORTRAN程序的示意图,它包含了一个主程序,一个模块,以及两个子例行程序。

图12-1 

钟表制作程序的结构 

在上面的例子里面,我们假设在装配一块钟表时,零件装配与工具配套分别由两个徒弟完成,那么等负责工具配套的徒弟把零件都放置在适当的工具旁边的时候,就可以让钟表匠开始总的钟表装配工作了。

因此模块ACCESSORY_BOX(附件箱)里面包含了子例行程序PARTS(零件)与TOOL(工具)所需要的一切数据与过程信息。

主程序调用了子例行程序TOOL,而主程序本身不需要模块ACCESSORY_BOX里面的信息。

12.2 

主程序说明了整个FORTRAN程序的逻辑结构,同时整个程序的运行就是从主程序的第一个可执行语句开始的。

不过从形式上看,一个主程序和外部子程序其实的非常类似的。

一个主程序包括如下三个基本部分:

说明部分。

这个部分定义了程序的数据环境。

运行部分。

整个程序从这个部分的第一个可执行语句开始,该部分给出了整个程序运行的逻辑结构。

内部子程序部分。

处于主程序内部的与主程序共享数据的过程。

下面我们分小节说明主程序的说明部分和运行部分,由于内部子程序部分由一个或多个内部过程组成,而内部过程的讨论见12.3,因此在12.2略过。

终止主程序运行的方式有如下两种:

在程序的任意位置执行STOP语句,就能即刻终止整个程序。

所谓任意位置,包括组

成程序的任意程序单位的任意位置。

程序的运行到达主程序的最后一个语句。

12.2.1 

主程序的组织

主程序的形式(R1101)如下:

 

[PROGRAMprogram-name]

[specification-part]

[execution-part]

[internal-subprogram-part]

END[PROGRAM[program-name]]

下面是一个最最简单的FORTRAN程序:

【例12-1】

END

下面是一个稍微有意思一点的最简单程序:

【例12-2】

PROGRAMHI

PRINT*,“HELLO”

主程序的一般规则如下:

●PROGRAM语句作为主程序的程序头是可选的,但是其他的程序单位都必须具有程序头。

●如果程序名称出现在END语句当中的话,那么该名称必须和PROGRAM语句里面的名称一样,并且放置在关键词的后面。

不能单独出现END语句当中。

●主程序不提供哑元。

●主程序不能在任何位置被引用,也就是说,主程序不能被直接或间接地递归运行。

●主程序不能包含RETURN语句和ENTRY语句,不过主程序里面的内部过程可以包含RETURN语句。

12.2.2 

主程序的说明部分

主程序的说明部分主要就是用来描述程序的数据环境。

主程序里面所能够包含的语句类型见表12-1,具体列出如下表12-2:

表12-2 

主程序说明部分允许使用的语句

ALLOCATABLE

PARAMETER

COMMON

POINTER

DATA

SAVE

DIMENSION

TARGET

EQUIVALENCE

USE

EXTERNAL

FORMAT

IMPLICIT

语句函数语句

INTRINSIC

类型声明语句

NAMELIST

主程序的说明部分的一般规则如下:

●OPTIONAL以及INTENT属性或语句都不能在主程序的说明部分出现,因为它们都只能应用于哑元。

●可访问性说明PUBLIC以及PRIVATE都不能出现于主程序,因为它们都只能应用于模块内部。

●在主程序里面,动态对象没有意义。

●尽管在主程序里面可以使用SAVE属性或语句,但它们在主程序里面并没有实际的作用。

12.2.3 

主程序的运行部分

主程序的运行部分由可执行语句构成,能够出现在主程序的运行部分的语句列出如下表12-3所示:

表12-3 

主程序运行部分允许使用的语句

ALLOCATE

GOTO

BACKSPACE

IF

CALL

IF结构

CASE结构

INQUIRE

CLOSE

NULLIFY

CONTINUE

OPEN

CYCLE

PRINT

READ

DEALLOCATE

REWIND

DO结构

STOP

END

WHERE

ENDFILE

WHERE结构

ENTRY

WRITE

EXIT

算术IF语句

FORALL

赋值语句

FORALL结构

计算GOTO语句

指针赋值语句

12.3 

内部过程

内部过程和外部过程的主要差别就在于它们的的位置不同:

内部过程必须封装在主程序或其他过程子程序内部,这就导致以下后果:

内部过程的名称是局部的而不是全局的;

内部过程只能被包含了它的定义的程序单位所引用;

内部过程能够访问它的宿主的数据对象;

内部过程可以递归,不能包含ENTRY语句,也不能作为实元传递。

构造内部过程的主要原因如下:

内部过程提供了能够很方便地访问宿主环境的过程。

内部过程提供了一种具有语句函数功能的多语句形式。

便于模块设计以及具有更好的软件工程效能。

内部过程之所以能够提高安全性以及灵活性,是因为其界面非常清晰。

宿主的内部过程部分的形式(R210)为:

CONTAINS

internal-subprogram

[internal-subprogram]…

其中的内部子程序由一个或多个内部过程组成,而内部过程或者是由如下形式(R1216)的函数组成:

function-statement

ENDFUNCTION[function-name]

或者是由如下形式(R1221)的子例行程序组成:

subroutine-statement

ENDSUBROUTINE[subroutine-name]

【例12-3】

PROGRAMWEATHER

FUNCTIONSTORM(CLOUD)

ENDFUNCTIONSTORM

其中的过程STORM就是主程序WEATHER里面的一个内部过程。

内部过程的一般规则如下:

●内部过程内部不能再包含内部过程,即内部过程不能嵌套。

●内部过程不能包含ENTRY语句。

●内部过程不能包含PUBLIC和PRIVATE属性或语句

●内部过程不能作为实元传递。

●内部过程的说明部分除了可以包含主程序的说明部分所许可的语句之外,还可以包含INTENT语句以及OPTIONAL语句。

●内部过程的运行部分除了可以包含主程序的运行部分所许可的语句之外,还可以包含RETURN语句。

●在CONTAINS语句之后,至少需要有一个内部子程序。

内部过程可以被它的宿主的运行部分引用,也能够被同一个宿主里面的所有内部过程引用,包括它自身,因此内部过程可以直接或间接地使用递归的形式。

内部过程名称属于局部名称,因此满足如下规则:

内部过程名称具有比相同名称的外部过程或固有过程更高的优先级。

内部过程名称必须不同于任何同一个宿主里面的其他内部过程的名称,也必须不同于任何通过模块进入宿主或进入该内部过程的名称。

内部过程的名称必须不同于任何宿主或自身内部的其他局部名称,也必须不同于通过USE语句可访问的名称。

有关宿主以及内部过程里面的其他名称所需要遵循的规则参见第15章有关宿主关联的内容。

12.4 

宿主关联

内部过程当中的某些变量有可能并非源自内部过程本身,而是从内部过程的宿主单位继承而来的,这样的变量被称为宿主关联的,它反映了内部程序与宿主在数据交流方面的密切关系。

宿主关联作为一种数据通讯方式,同样存在于模块过程与其作用域单位之间,因此我们将在第15章的更为一般的情形下讨论它。

12.5 

同样外部子程序是由一个或多个外部过程组成,因此下文当中,我们将根据具体的上下文交替使用外部子程序与外部过程这两个概念。

外部过程与内部过程从语法上来看,实质上是一致的,因为毕竟它们都是属于过程,因此外部子程序的语法形式和内部子程序一样,即:

外部子程序由一个或多个外部过程组成,而外部过程或者是由如下形式(R1216)的函数组成:

这是两种不同风格的过程形式。

同时,外部过程与内部过程又具有如下一些很重要的差别:

对于一个FORTRAN程序来说,外部子程序是全局性的,因为它可以在任何位置被调用或引用,相反,内部过程则只是对于它的宿主而言是已知的。

外部过程的界面在它被其他过程引用的时候,并非已知的,因为外部过程一般都是单独编译的;

相反,对于内部过程来说,它是由它的宿主单位编译的,因此在它的宿主单位引用它的时候,它的界面信息必定已经给出了。

具有与生俱来的显式界面是内部过程或模块过程的一个很大的优点,它的好处将在第13章讨论。

相比之下,外部过程就只能单独给出它的界面信息。

从FORTRAN标准语法上来看,外部过程可以包含内部过程,而内部过程则不能包含内部过程,不过也有许多FORTRAN的实现都允许内部过程的嵌套。

下面是外部过程的两个不同形式的例子:

【例12-4】

FUNCTIONCIRCLE(NET)

INTEGERCIRCLE

CIRCLE=NODE

ENDFUNCTION

这个例子使用了函数作为外部过程。

【例12-5】

SUBROUTINETAYLOR(I,J)

I=…

J=…

ENDSUBROUTINE

这个例子使用了子例行程序作为外部过程。

外部子程序的一般规则如下:

●外部子程序作为程序单位的头,即FUNCTION语句或SUBROUTINE语句,是不能省略的,这点与主程序不同。

●如果在END语句出现过程名称,那么它必须与头语句里面的过程名称一样。

●用于哑元的INTENT和OPTIONAL属性或语句可以出现在外部子程序的说明部分,注意它们只能应用于哑元。

●外部子程序的说明部分和运行部分都可以包含ENTRY语句;

运行部分可以包含RETURN语句。

●外部子程序不能包含用来说明可访问性的PUBLIC或PRIVATE属性或语句。

●外部过程可以采用直接或间接的递归形式,这时,在该过程的头语句里面必须使用关键词RECURSIVE。

●一个外部子程序对于在它内部定义的内部过程而言,就是宿主单位。

●外部过程名称可以在过程引用的时候作为实元来使用,相应的哑元就是引用它的过程里面的过程哑元。

无论是外部过程,内部过程或模块过程,作为过程的更加一般的讨论参见第13章。

12.6 

模块

模块是到了FORTRAN90版标准之后才引入的一个极其强大的程序结构单位形式。

只要是多于一个程序单位都需要使用的任何东西,都可以封装在一个模块里面,供相关的程序单位使用。

在FORTRAN的早期版本当中,为了解决一些程序要素的重复使用问题,使用了INCLUDE行,它的功能纯粹只是把一段源码原封不动地引入某个程序(参见第四章),相当于“COPY+PASTE”的功能,以避免在重复写入别处的源码段时可能出现的笔误,也节省编写源码的工作量。

但是这样一种解决方式是非常有局限性的,因为这完全只是一种形式上的重用,根本不具有灵活性与多功能性,因此到了制订FORTRAN90标准的时候,就引入了符合现代编程风格的模块结构,使得INCLUDE行逐渐退出了历史舞台。

模块为FORTRAN解决了如下的问题:

解决了大量的与全局性数据公用块相关联的可靠性问题,因为对于全局性数据来说,名称关联比存储关联更为有必要。

提供了更为可靠的定义派生类型的方式。

许多的情形下都要求显式的界面,而模块正好满足了这种需求。

提供了极其重要的信息隐藏功能,模块保证了可靠性所要求的有效的封装与隐藏功能。

尽管模块可以包含被其他程序单位的运行部分引用的可执行过程,但它自身并不是可执行的程序单位,实质上它只是被动地提供信息,在这个意义上,模块就已经是足够强大的管理程序的组织与简化程序设计的工具。

12.6.1 

模块的组织

模块的语法形式(R1104)为:

MODULEmodule-name

[module-subprogram-part]

END[MODULE[module-name]]

模块的名称如果出现在END语句,那么必须和MODULE语句里面的模块名称一样。

12.6.2 

模块的说明部分

模块的说明部分与其他的程序单位的说明部分非常类似,它可以包含的语句如下表12-4所示:

表12-4 

模块说明部分允许使用的语句

PRIVATE

PUBLIC

模块的说明部分的一般规则如下:

●不允许使用OPTIONAL和INTENT属性或语句。

●不允许使用ENTRY语句。

●不允许使用FORMAT语句

●不允许使用动态对象。

●不允许使用语句函数语句。

●可以使用PUBLIC和PRIVATE属性或语句。

注意在模块的说明部分中使用SAVE属性或语句是非常必要的,因为SAVE能够保证模块里面的数据对象,不会受到使用该模块的其他程序单位的影响。

如果没有使用SAVE属性或语句的话,那么相应的数据对象常常会被使用该模块的其他程序单位去定义,而使用SAVE属性或语句,则能够保证相应的数据对象保留其定义状态。

【例12-6】

MODULEDATA1

SAVE

INTEGER:

X,IX

REAL:

K=0.01

Y(10,20),Z(20,30)

ENDMODULEDATA1

SUBROUTINETASK1

USEDATA1

ENDSUBROUTINETASK1

在上面的模块DATA1当中,声明了三个标量变量:

X,IX和K,其中K给出了初始值,还有两个数组:

Y(10,20),Z(20,30),这5个数据对象都是全局性的,都可以在任何时候被其他的程序单元使用。

在后面的子例行程序TASK1里面就通过USE语句使用了这5个变量。

12.6.3 

模块的子程序部分

在语法上,模块的子程序部分类似于主程序的内部过程部分或外部子程序。

模块的子程序部分由一个或多个模块过程组成,它们通过宿主关联共享模块的数据环境,不过模块的子程序部分与内部子程序有如下两个基本的差别:

模块过程的组织结构,规则与限制都与外部过程的一样,而与内部过程的不同,例如模块过程可以包含内部过程,而内部过程不能包含内部过程。

模块过程并非严格地局限于宿主模块,也不是全局性地面对整个程序,只有使用了模块的程序单位才

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 文学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1