fortran95的使用方法6Word下载.docx
- 文档编号:20975131
- 上传时间:2023-01-26
- 格式:DOCX
- 页数:24
- 大小:131.79KB
fortran95的使用方法6Word下载.docx
《fortran95的使用方法6Word下载.docx》由会员分享,可在线阅读,更多相关《fortran95的使用方法6Word下载.docx(24页珍藏版)》请在冰豆网上搜索。
名称;
作用域;
关联;
定义状态。
即任何的FORTRAN程序里面的对象都需要给予一个名称,而所有的名称都能够按照变量与值的关系,建立相对的层级结构。
作用域就是一个FORTRAN程序对象能够被识别,被访问的程序单位的范围。
关联就是在相同名称或不同名称下,进行相应的值的交换。
定义状态就是必须能够随时确定一个变量是否具有良好的定义,从而能够判别基于该变量的通讯是否有效。
可以形象地说,这4个概念完备地描述了程序的数据流的一言一行,一动一止。
下面我们就分别说明通讯的这4个核心概念。
15.1
通讯与名称
给对象命名是进行有关对象的通讯的前提。
(试想一下我们要告诉别人“起火了”,如果我们不知道描述“火”的词汇,那该如何说清楚意思呢?
)
为了保证通讯时不发生歧义,最极端的做法就是给世界上的每一个对象给予一个唯一的名称。
然而这是不可能实现的,因为世界是无限大的。
不过即使在有限的范围内,也是非常不明智的。
例如在FORTRAN语言里面已经预先定义了名称SUM的涵义,即用名称SUM来命名一个固有函数,表示一种作用于数组的运算。
然而如果在一个程序里面,并没有涉及到任何与数组有关的计算,那么我们完全可以安全地使用名称SUM来形象地命名一个自定义的运算,例如两个属于派生类型的对象的组合。
运用容易记忆的英语词汇或缩写来表示具有相应涵义的对象,这是一种良好的编程习惯,不能为了避免名称的重复而被迫记忆大量的名称。
又例如一个大型的FORTRAN程序,事实上是无法由一个人编写完成的,那么如果由多个人分块编写的话,又如何能够保证他们使用的名称是绝对一致的呢?
即相同的对象具有相同的名称,不同的对象具有不同的名称。
这对于每个小程序单位都有成千上万个语句的大型程序,是绝对不现实的要求,也是完全不必要的要求。
因为不同对象的重名问题,可以很轻易地通过约定名称的有效范围而获得解决,这就是下节讨论的作用域的概念。
15.2
作用域
任何具有名称的对象都具有相应的作用域,也就是存在一个明确的约定,该名称在FORTRAN程序的哪个范围内,是被识别为该对象,而且引用该名称就意味着访问该对象。
在一个FORTRAN程序里面明显具有名称的对象包括变量,常量,过程,数据块子程序,模块,名称列表集合等。
它们都具有相应的作用域。
还有其他的对象,例如算符,赋值符号,标签,输入输出单位编目等,它们都已经不再需要额外的名称,因为这些对象在被定义出来时,就已经具有天然的名称,因此它们也具有相应的作用域。
对象的作用域可以大到包括整个程序,也可以小到只有一个语句的某个部分。
当一个对象的作用域为整个程序时,该对象就称为全局对象。
例如一个程序里面的外部过程,在程序的任意位置,都可以随时引用它的名称,而不会发生无法访问该外部过程的情形。
当一个对象的作用域还没有达到整个程序时,该对象就称为局部对象。
例如语句标签,一般只在该语句所处的程序单位里面有效。
当一个对象的作用域只是该对象所处的语句,甚至只是语句的一个部分时,该对象就称为语句对象。
例如语句函数的哑元就是典型的语句对象。
一般说来,如果一个对象的作用域恰好构成一个程序单位,那么相应的作用域也称为作用域单位,这样一来,许多更小型的作用域,例如语句函数,FORALL结构,隐式DO语句等,就不能称为作用域单位了。
作用域单位一般有如下三种情形:
派生类型定义是一个作用域单位;
一个过程界面体,在排除其中可能的派生类型定义,以及包含在派生类型定义里面的过程界面体之后,构成一个作用域单位;
一个程序单位,或者子程序,在排除其中可能的派生类型定义,过程界面体以及包含在其中的子程序之后,构成一个作用域单位。
在一个作用域单位里面还可以包含其他的作用域单位,不过这种包含关系不完全与结构之间的嵌套关系相同。
因为具有包含与被包含关系的两个作用域单位可以出现如下两种情形:
被包含的作用域单位,可以继承包含它的作用域单位的数据环境;
例如派生类型定义,模块过程,内部过程等都继承包含自身的作用域单位的隐式类型规则。
被包含的作用域单位不继承包含它的作用域单位的数据环境。
例如界面块不继承包含自身的作用域单位的隐式类型规则。
因此在某些情形下,一个作用域需要排除包含其中的作用域单位之后才构成一个作用域单位。
作用域与作用域单位的相互关系参见示意图15-1里面的表示。
图15-1
作用域与作用域单位的相互关系
在上面的示意图15-1当中,最大的方框表示一个FORTRAN程序,它表示了一个整体,显然它不构成一个作用域单位。
然后是其中的4个方框,分别表示1个主程序,2个外部过程A和D,1个模块E。
它们都是作用域单位,但是得排除它们内部出现的方框,即内部过程B和C,界面块,派生类型定义,以及模块过程F和G。
因为它们同样是作用域单位。
由于在上面的FORTRAN程序例子当中,内部过程B和C,界面块,派生类型定义,以及模块过程F和G的内部不再出现内部过程,界面块,派生类型定义,以及模块过程,所以它们都不再需要排除什么,就构成一个作用域单位。
不过一般在它们内部还包含其他的作用域单位是非常常见的。
15.2.1
名称的作用域
一个名称的作用域存在如下4种情形:
整个程序,即该名称为全局性的;
一个作用域单位,即该名称为局部性的;
一个结构,即一个FORTRAN结构的作用域;
一个语句,即一个FORTRAN语句或语句的某个部分作为作用域。
下面按照范围从大到小的顺序分别予以说明。
1.全局情形
能够具有全局性名称的对象包括:
主程序;
外部过程;
模块;
数据块程序单位;
公用块。
正是因为这些对象的名称具有全局性,因此它们在一个FORTRAN程序内部不能使用相同的名称。
2.局部情形
能够具有局部性名称的对象包括如下3个类别:
变量,常量,控制结构,语句函数,内部过程,模块过程,哑过程,固有过程,自定义类过程,派生类型和名称列表集合。
派生类型的成员。
之所以把派生类型的名称与它的成员的名称分为不同的类别,是因为不同名称的派生类型,完全可以具有相同名称的成员。
变元关键词。
之所以把具有显式界面的过程的名称与其变元关键词的名称分为不同的类别,是因为不同名称的过程,完全可以具有相同名称的变元关键词。
局部性名称的作用域的一般规则如下:
●在一个作用域单位里面可以访问的全局性对象的名称,不能用来作为一个该作用域内部的局部性对象的名称,除非该局部性对象和一个公用块同名。
●一个非类型的局部性对象的名称,在它的作用域单位里面,以及它的同一个名称类别里面,必须是唯一的,只有在不同的作用域单位,或者不同的名称类别里面,才可以把该名称用于另外一个不同的对象。
在其他作用域单位里面的对象,不管其使用的名称是否与此作用域单位里面的对象所使用的名称相同,都有可能通过关联,而导致实际上是同一个对象。
●一个类型的局部性名称,可以用于同一个作用域单位里面的不同过程。
●在一个作用域单位里面的同一个名称可以用来表示不同名称类别里面的对象。
例如一个变元关键词可以和一个逻辑型变量具有相同的名称。
●派生类型的成员的作用域就是该类型定义,当该成员被用于结构引用时,它的作用域就是该结构引用。
●变元关键词属于一个单独的名称类别,因此一个变元关键词的名称可以在同一个作用域单位里面,用作其他类别对象的名称,例如其他过程的变元关键词,过程,或变量的名称。
●如果在程序当中出现了一个公用块与一个局部性对象的名称的雷同,那么该名称只有在表示公用块时,才是全局性的。
在引用该名称时,它所指称的对象的唯一性由该名称的上下文保证。
●一个固有过程的名称可以在不出现该固有过程的作用域单位里面用作局部性名称。
也就是说一旦某个固有过程的名称在某个作用域单位里面被用来作为一个局部性名称,比方说一个变量的名称,那么在整个该作用域单位里面,该固有过程本身都不能出现了。
●对于每个函数以及不具有结果变量的函数对象,在它的子程序作用域单位里面,都默认存在一个与该函数或函数对象同名的一个局部变量,该局部变量用来在本作用域单位里面定义该函数或函数对象的结果值。
●对于每个内部过程或模块过程,它的名称对于它的宿主作用域单位而言都是局部的。
类似地,对于模块过程内部的任意对象名称,对于它的宿主作用域单位而言,也都是局部的。
3.结构的情形
在FORTRAN里面,可以用作作用域的结构只有FORALL结构。
在FORALL语句或结构里面的指标变量的名称具有的作用域为该FORALL语句或结构的赋值语句的作用域。
该指标变量的名称在其他地方都是用作标量变量名称,而在作用域单位的任何位置它都是整型变量。
FORALL语句或结构里面的指标变量是具有一个大于一个语句同时又小于一个作用域单位的作用域的唯一的例子。
4.语句的情形
一个名称的作用域只限于一个语句或语句的一个部分的情形有以下两种:
一个语句函数的哑元的名称;
在一个DATA语句里面的隐式DO列表或一个数组构造器里面的DO变量名称。
这些名称都可以在该语句的作用域单位的其他地方用作标量变量名称或公用块名称,而不至于出现任何的名称冲突。
语句里面的名称的一般规则如下:
●一个语句函数的哑元的名称的作用域就是该语句,它的类型与种别参数都在该语句所在的作用域单位里面得到声明。
●在一个DATA语句里面的隐式DO循环或一个数组构造器里面的DO变量名称的作用域就是该DO变量所在的语句部分。
该DO变量的类型必须是整型,而它的种别参数则由它所在的作用域单位声明。
●在隐式DO列表里面的DO变量的作用域只是它所在语句的一部分,而在一个DO结构里面的DO变量的作用域则是该结构所在的作用域单位。
这两种是完全不同的。
●在输入输出项列表当中的隐式DO里面的DO变量的作用域,为该输入输出语句所在的程序单位。
15.2.2
标签的作用域
标签总是局部性的。
也就是说在一个作用域单位里面一个标签总是指称同一个语句,而在不同的作用域单位里面,可以同时使用同一个标签来指称不同的语句。
15.2.3
输入输出单位的作用域
外部输入输出单位的编目总是全局性的。
也就是说,在一个FORTRAN程序里面,无论一个输入输出单位的编目出现在什么位置,它都指称同一个输入输出单位。
15.2.4
算符的作用域
算符分为固有算符和自定义算符两种。
固有算符是全局性的;
而自定义算符是局部性的。
一个固有算符的符号也可以用作自定义算符的符号;
而且算符还可以具有类的属性,即同一个算符可以用来指称几个运算符号,它们具有不同的涵义。
而程序是通过相应算元的类型,种别参数以及秩来获得对它们的辨别的。
15.2.5
赋值的作用域
赋值分为固有赋值和自定义赋值两种。
固有赋值是全局性的;
而自定义赋值是局部性的。
赋值符号(=)总是全局性的,同时也可以具有局部性的定义;
而且赋值还可以具有类的属性,即不同的赋值运算可以使用同一个赋值运算符号来指称,它们具有不同的涵义。
而程序是通过赋值符号=左右两边的对象的类型,种别参数以及秩来获得对它们具体涵义的辨别的。
15.2.6
非歧义过程引用的作用域
所谓非歧义的过程引用,是指引用的过程名称在相应的作用域单位里面,是一个种过程名称,它与该作用域单位里面的任何类过程名称都不相同。
非歧义的过程引用包括如下的情形:
引用内部过程;
引用哑过程;
引用语句函数;
引用属于固有过程的与类过程不重名的种过程名称;
引用模块过程或外部过程,它不能够出现在具有所在作用域单位的类声明的界面块里面,或者是可以通过使用关联或宿主关联来访问的。
只有属于外部过程的种过程名称是全局性的,所有其他的种过程名称都是局部性的。
在满足以下条件的情形下,涉及到类过程名称的过程引用也可以是非歧义的。
即如果任意两个过程具有同一个类过程名称,那么在它们的哑元列表当中,至少得有一个非可选的哑元同时满足下面两个条件:
或者是在另外的哑元列表里面与该哑元所处列表位置相同的位置不存在相应哑元,或者是与相应哑元具有不同的类型,种别以及秩的不同组合模式。
或者是该哑元具有与另外那个哑元列表里面的所有哑元都不同的名称,或者是即使存在同名的哑元,也与同名哑元具有不同的类型,种别以及秩的组合模式。
一个非逐元的种过程有可能引用一个类过程作为它的哑元,同时一个与类过程重名的逐元过程也引用类过程作为它的变元,在这种情况下,该非逐元种过程就用于解决类过程引用所带来的名称歧义问题。
不管类名称是固有的,还是由具有类说明的界面块所定义的,上面的规则都是适用的。
而且它们还适用于算符类的名称以及赋值符号类。
对于固有函数来说,固有函数的类名称是全局性的,而自定义的类名称为局部性的。
15.2.7
歧义过程引用的名称处理方法
在FORTRAN程序里面,一个过程引用发生在如下几种情形里面:
情形1.运行一个CALL语句时;
情形2.运行一个经过定义的赋值语句时;
情形3.运行一个经过定义的运算时;
情形4.运行一个包含函数引用的表达式时。
在情形2里面,涉及到了作为类名称的赋值符号(=),这时在相应作用域单位里面必定存在一个具有ASSIGNMENT类说明的界面块,或者是通过使用关联或宿主关联可以访问定义了该赋值的外部子例行程序或模块子例行程序,在这种情况下,就必须运用13.7.7节,13.8.5节以及15.2.6节的相应规则来决定究竟引用哪个种子例行程序。
在情形3里面,涉及到了作为类名称的运算符号,这时在相应作用域单位里面必定存在一个具有OPERATOR类说明的界面块,或者是通过使用关联或宿主关联可以访问定义了该运算的函数或模块函数,在这种情况下,就必须运用13.7.7节,13.8.4节以及15.2.6节的相应规则来决定究竟引用哪个种函数。
在情形4里面,如果表达式的某个项的形式是由一个名称后接用括号括起来的表达式与过程名称的列表,其中的过程名称在本作用域单位里面没有被声明为数组名称,那么该表达式就包含了一个函数引用。
在情形1与情形4里面,对于有可能出现的过程名称引用歧义问题,必须按照以下的规则序列,逐步地来决定应该被引用的种过程。
如果引用的过程名称是所在作用域单位里面的一个哑元,那么该哑元就是一个哑过程,并且实际应该引用相关联的作为实元的过程。
如果引用的过程名称是出现在所在作用域单位里面的一个EXTERNAL语句当中,那么就引用该名称所指称的外部过程。
如果引用的过程名称是指向一个可访问的内部过程或语句函数,那么就引用该内部过程或语句函数。
如果引用的过程名称是类过程名称,而该类过程名称是在一个所在作用域单位里面的界面里出现,或者是在一个通过使用关联或宿主关联可以访问界面块里面出现,同时该引用还包含一个有关该类过程名称的种性质的类型,种别以及秩的组合模式的说明,那么就引用具有该类型,种别以及秩的组合模式的相应种过程,运用13.7节的规则就决定了该种过程,而13.7.7节以及15.2.6节的规则则保证了这样的种过程至多只存在一个。
如果过程引用是由一个引用逐元过程的逐元引用组成,而同时又不存在非逐元的过程能够匹配相应的类型,种别以及秩的组合模式,那么就引用该逐元过程。
如果引用过程名称出现在所在作用域单位里面的一个INTRINSIC语句当中,那么就引用该名称所指称的相应固有种过程。
如果引用的过程名称,是可以通过使用关联获得访问的,那么就引用相应的种过程。
另外,由于可能出现改名现象,引用的过程名称可能会与模块里面的过程名称不一致。
如果引用所在的作用域单位还具有一个宿主作用域单位,而如果引用歧义问题已经在其宿主作用域单位里面通过上面的规则加以解决,那么在本作用域单位里面也就不存在歧义问题了。
如果引用的过程名称同时是类过程和种过程的名称,而实元与其中特定的某个固有过程的特征相匹配,那么就引用相应的固有种过程。
如果引用过程名称不是一个类过程名称,那么就引用具有该名称的外部过程。
如果以上规则都不能解决问题,那么该引用就是非标准的,或非法的引用。
15.3
关联
在明确了每一个名称或对象的作用域之后,进行通讯的主要手段,就是在不同的作用域之间建立对象之间的关联。
所谓建立关联,同样是以对象的名称为基础的,因为按照直观的理解,无论是什么形式的通讯,都是以能够进行名称的传递为前提的。
只不过在不同形式的通讯里面,名称一般也具有不同的形式而已。
一个FORTRAN程序的运行过程就是通过名称对相应对象的操作过程,名称的作用在于为程序辨认相应对象的属性提供依据,或者还可以为程序指出对象的存储位置。
因此在程序当中进行的通讯无非就是一些交换名称的过程,即在不同的作用域单位之间给出指称同一个对象的名称,或者在同一个作用域单位里面给出指称同一个对象的不同名称,就是所谓通讯过程的实质,而关联的含义就是用来完成这两种任务。
关联具有以下4种形式:
名称关联
即直接使用名称进行关联,这种关联必定是在不同的作用域单位之间进行。
名称关联包括变元关联,使用关联,宿主关联3种类型。
指针关联
所谓指针关联的功能就是能够在一个作用域单位里面实现名称的动态关联。
存储关联
存储关联通过存储序列实现数据对象之间的关联。
在相同的作用域单位里面是通过EQUIVALENCE来实现存储关联的,而在不同的作用域单位之间则是通过COMMON来实现关联的。
序列关联
所谓序列关联其实就是名称关联与存储关联的组合,也是属于名称关联的变元关联的一种特殊形式。
序列关联在不同作用域单位的名称之间实现关联。
在下面的示意图15-2,和图15-3里面,给出了两个实现各种关联的可执行程序的例子。
分别是在两个非模块作用域单位之间的关联和一个模块作用域单位与另一个非模块作用域单位之间的关联。
图15-2
两个非模块作用域单位之间的关联
图15-3
一个模块作用域单位与另一个非模块作用域单位之间的关联
15.3.1
名称关联
尽管从实质看来,关联总是要通过名称来进行的,不过我们单独把在不同作用域单位之间相同或不同名称实现的关联称为名称关联。
名称关联包括如下3种形式:
变元关联;
使用关联;
宿主关联。
下面分别予以说明。
1.变元关联
所谓变元关联就是在一个包含了过程引用的作用域单位里面的实元和另一个包含了对被引用过程的定义的作用域单位里面的虚元之间所建立的关联,即把可能相同也可能不同的处于不同作用域单位的名称,指称同一个实体对象。
通过变元关联而实现了实哑通讯的实元,是一个变量,或过程,或表达式的名称,而相应的哑元则是出现在过程定义当中的用来引用实元的名称或表达式。
这种关联在程序的执行离开该过程之后,就被撤消了,即在被引用过程运行当中具有关联的实元名称与哑元名称在程序退出该过程之后,就不具有关联关系了。
2.使用关联
使用关联在一个模块作用域单位和一个通过USE语句引用了该模块的作用域单位的相同名称或不同名称之间建立关联。
通过这种关联就实现了使用USE语句的作用域单位对被引用模块内部的对象的访问。
按照默认的约定,模块内部所有的具有公用属性的对象都能够接受访问。
在USE语句里面可以选择性地对需要访问的对象进行重命名,还可以运用ONLY选项来挑选需要访问的对象。
使用关联的一般规则如下:
●如果在USE语句当中使用了重命名,那么相应局部名称的一切属性都向模块里面的被关联属性看齐。
而且对于USE语句所属作用域单位里面的能够访问被引用模块的对象,除了可以改变它的访问能力之外,都不具有重说明属性的能力。
●在USE语句里面对一个对象进行了改名,那么模块里面的原始名称就可以在该USE语句所属作用域单位里面作为局部名称使用,而不会导致名称冲突。
●模块内部的对象的PUBLIC与PRIVATE属性都只能够由模块自身来规定,引用模块的作用域单位不能够改变模块内部对象的可访问性。
3.宿主关联
宿主关联是在一个内部过程,或模块过程,或派生类型定义里面的对象名称与它的宿主作用域单位里面的对象名称之间建立关联。
直观而言,宿主关联就是为了使得一个宿主作用域单位里面的名称都能够被其内部的过程或派生类型定义所访问,当然前提是这些过程和派生类型定义都是能够被其宿主作用域单位所访问的。
尽管宿主关联不具有使用关联那样的改名机制,以防止出现名称冲突,但是宿主关联可以很容易地通过在内部过程,或模块过程,或派生类型定义里面,对某个名称进行局部声明,而防止它所在的作用域单位访问其宿主作用域单位里面的同
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- fortran95 使用方法