




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第7章 属性的声明最后,对于数据我们剩下的工作,就是如何运用FROTRAN语言来完整地加以描述。FORTRAN语言完成对数据的描述的语法单位是数据声明语句,在前面2章里面,我们整理好问题当中需要涉及的数据及其结构之后,要以FORTRAN语言写下来,就是使用FORTRAN的声明语句,这些语句的句法设计保证能够完备的描述我们关于数据所需要说明的一切属性。数据对象首先需要予以说明的当然就是它的类型,因此我们首先给出对象的类型声明语句,特别地,需要说明在最初FORTRAN标准里面遗留下来的一种数据类型描述方法隐式类型描述法,然后讨论各种数据对象所可能具有的属性。 数组属性; 指针属性; 值特征; 对象
2、可访问性与使用属性; 特征兼容性; 自动数据对象; 存储关联。由于本章集中讨论FORTRAN的声明语句,而声明的对象除了数据之外,其他的程序对象,例如函数,过程等也需要声明其类型或属性,因此本章一并讨论对其他程序对象的声明: 过程属性; NAMELIST语句; 7.1 属性及其声明方式所谓一个对象的属性,就是程序使用该对象的方式。本章所讨论的属性的大体分类与作为其名称的关键词见表7-1:表7-1属性的分类及其关键词数据类型 INTEGER REAL(以及DOUBLE PRECISION) COMPLEX LOGICAL CHARACTER TYPE(派生类型的名称由用户命名)数组属性 DIME
3、NSION ALLOCATABLE指针属性 POINTER TARGET值设置 DATA PARAMETER对象可访问性与调用 PUBLIC PRIVATE INTENT OPTIONAL SAVE过程属性 EXTERNAL INTRINSIC对象关系属性 NAMELIST EQUIVALENCE COMMON 这些关键词的使用,或者说属性的声明有2种方式: 在类型声明时附加属性说明,这种语句形式侧重在给出数据对象,属性说明是附加的; 使用单独的属性声明语句,这种语句形式侧重在说明属性本身。之所以会出现2种声明方式,完全是历史的缘故。FORTRAN的早期版本里,任何的对象属性说明,都是运用单独
4、的属性声明语句,如果一个数据对象同时具有多种属性,就需要使用相应的多个属性声明语句,从程序阅读的角度来看,会显得很烦琐,因此到了FORTRAN90和95版本,只要在程序单元当中需要声明一个数据对象的类型,那么就可以把它的其他所有属性都附加到它的类型声明语句当中,使得程序显得更加紧凑。【例7-1】 我们要定义2个实型变量X,Y,同时还要声明它们都具有指针属性,在早期FORTRAN语言里写为: REAL X,Y POINTER X,Y换一种更加紧凑的写法就是把这2条语句写为1句: REAL POINTER:X,Y之所以我们还需要讨论单独的属性语句,主要是有时候需要保持源码的向前兼容性,而且在少数情
5、况下,这2种形式也并完全等价。因此在本章在讨论各种属性的声明方式的时候,将首先给出面向数据对象的声明方式,然后给出等价的面向属性的声明方式。在这2种表示属性的方式里,同样由于历史的缘故,数组的维度属性DIMENSION既可以附加在类型声明语句当中表述,也可以单独声明,实际上DIMENSION这个关键词属于老式FORTRAN的遗留物,在新的表述方式里面,完全可以省略它。【例7-2】 COMPLEX X DIMENSION X(35) SAVE X COMPLEX X(35) SAVE X COMPLEX,DIMENSION(35),SAVE:X COMPLEX,SAVE:X(35)以上4种表述方
6、式是完全等价的,显然最后一种最简洁。在一个程序单元里面,引用一个数据对象的前提是已经声明了它的种种必需属性,数据对象的各种属性里面,最为基本的当然是数据对象的类型,然后还需要声明其各种必需的属性,这样该数据对象才能被程序正确地调用访问。然而在一个实际的程序里面,数据对象的声明在表面上可能并不是完备的,同时又不是非法的语法,出现这种情况的原因如下: 在FORTRAN的早期版本里,为了求简化的缘故,使用了一种隐式约定数据类型的方式,即通过数据对象的名称的第一个字母来分辨其所属类型,这种类型声明方式被后来的FORTRAN版本一直沿用下来了,因此如果一个程序单元里出现的数据对象没有经过类型声明语句的专
7、门声明,则需要考虑其是否属于隐式声明。相反,如果想排除这种隐式声明的影响,则需要另外单独加以IMPLICIT NONE语句作为声明。 任何其他的属性如果没有出现的话,或者是因为该数据对象不需要某种属性,或者是该数据对象的某种属性采取了默认设置。从上面的分类表7-1可以看到,FORTRAN的属性除了用来说明数据类型的属性之外,其他属性都是针对不同的数据类型或程序对象,以及它们的各种特征的。例如数组属性只是用来说明数组,指针属性只是用来说明指针,而过程属性只是用来说明过程,下面将分类讨论这些属性。7.2 类型声明语句 我们在讨论第5章讨论数据类型的时候给出数据类型的基本声明语句的句法形式,这里将侧
8、重于数据类型的声明与其他相关属性的兼容,因为从语言的简洁与自然的角度出发,把一个数据对象的类型和其他属性都归结为一条数据声明语句是非常可取的,所以我们得到如下的一般的类型声明句法形式(R501): type-specification ,attribute- specification: entity-declaration-list即作为选项,在一条数据对象的类型声明(type-specification)语句当中,在数据项声明的列表(entity-declaration-list)之前,给出相应的属性说明(attribute- specification),方括号表示可选。 类型说明(ty
9、pe-specification)的一般句法形式(R502)是如下几种形式之一: INTEGER kind-selector REAL kind-selector DOUBLE PRECISION COMPLEX kind-selector CHARACTER character-selector LOGICAL kind-selector TYPE(type-name)其中种别选择符(kind-selector)的句法形式(R506)为: (KIND = kind-value)其中种别值(kind-value)是一个标量整型表达式。 属性说明(attribute- specification
10、)的一般句法形式(R503)为如下几种形式之一: PARAMETER ALLOCATABLE DIMENSION(array- specification) EXTERNAL INTENT(intent-specification) INTRINSIC OPTIONAL POINTER SAVE TARGET access- specification其中的可访问性说明(access- specification)包括PUBLIC和PRIVATE。 数据项声明的一般句法形式(R505)为如下2种形式之一: object-name (array- specification) *characte
11、r-length initialization function-name (array- specification) *character-length其中初始化(initialization)的一般句法形式(R505)为如下2种形式之一: = initialization-expression =NULL() 类型声明的一般规则如下: 对数据对象的说明优先于隐式类型描述,即隐式类型描述法永远只是在数据对象没有获得任何说明的情况下的默认法则,而显式说明既可以与隐式法则一致,也可以不一致。 在一个类型声明语句当中,同一个属性只能出现一次。 在一个作用域内,一个数据项的任何属性只要约定了一次,
12、就不可再次约定。 种别选择符所取的种别值只能是编译系统所许可的相应类型的种别参数之一。 字符长度(character-length)选项只能出现在CHARACTER类型的声明语句当中。 如果使用初始化语句,则必须在数据项声明前使用双冒号(;)。 如果数据变量被初始化设置为数组,那么该数组的形状一定要得到说明,或者是在类型声明语句当中,或者是在同一个作用域内此前的属性声明语句当中。 如果数据对象被赋予PARAMETER属性,那么其中必须包含初始化语句。 如果在初始化语句当中出现符号=,那么该被初始化的对象必定具有POINTER属性;如果在初始化语句当中出现符号=,那么该被初始化的对象肯定不具有P
13、OINTER属性。 所谓函数名称(function-name),或者是一个外部函数的名称,或者是一个固有函数的名称,或者是一个函数哑过程的名称,或者是一个语句函数的名称。 一个数组函数名称或者是被指定为显形数组,或者是具有POINTER属性,从而被指定为待定形数组。有关属性声明的其他规则以及属性之间的兼容性在后面会详悉讨论。【例7-3】 下面是一些附加了其他属性的数据类型声明语句: REAL, INTENT(IN) : COS REAL, INTRINSIC : SIN INTEGER X(25) LOGICAL,DIMENSION(10,15):RESULT1,RESULT2 INTEGER
14、,PARAMETER:SHORT=SELECTED_INT_KIND(4) COMPLEX : SQUARE_ROOT = ( 2.76, -0.85) REAL, ALLOCATABLE : X( : , : ) TYPE, POINTER : CURRENT_OF_SAMPLE = NULL()7.2.1 整型INTEGER语句声明了整型数据对象的名称,同时也可以附加种别参数以及其他属性。如果给出种别选择符,即说明该整型数据的表示方法。声明一个数据对象属于整型数据的基本语句句法为: INTEGER ( KIND = kind-value ) , attribute-list : entry
15、-list【例7-4】 以下这些声明语句主要是要说明数据项:INTEGER XINTEGER DIMENSION(:), POINTER : days, hoursINTEGER(SHORT)RED_BALLINTEGER(2) POINTER : k, limitINTEGER(1) DIMENSION(10) : min【例7-5】 以下这些声明语句主要是要说明数据的属性: INTEGER days, hours INTEGER(2) k, limit INTEGER(1) min DIMENSION days(:), hours(:), min (10) POINTER days, ho
16、urs, k, limit7.2.2 实型REAL语句声明了实型数据对象的名称,同时也可以附加种别参数以及其他属性。如果给出种别选择符,即说明该实型数据的表示方法。双精度实型数据还可以使用DOUBLE PRECISION语句加以声明,当然与在REAL语句当中使用种别参数是完全等价的。由于DOUBLE PRECISION本身指出了精度表示方法,因此不能再在后面附加种别选择符。不过DOUBLE这个词也可以作为一个命名整型常量,取双精度实型的种别参数值,这样就可以使用REAL(DOUBLE)来声明双精度实型数据了。实型数据的声明的格式如下: REAL ( KIND= kind-value ) , a
17、ttribute-list : entry-listDOUBLE PRECISION ,attribute-list : entry-list【例7-6】 下面是各种形式的主要说明数据项的声明语句: REAL (KIND = high), OPTIONAL : testval REAL, SAVE : a(10), b(20,30) DOUBLE PRECISION,POINTER:A,B(:,:) DOUBLE PRECISION,DIMENSION(5,10):TABLE1,TABLE2 REAL(DOUBLE),POINTER:A,B(:,:) REAL(DOUBLE),DIMENSIO
18、N(5,10):TABLE1,TABLE2【例7-7】 下面是各种形式的主要说明数据属性的声明语句:REAL (KIND = high) testval REAL a(10), b(20,30) OPTIONAL testval SAVE a, b DOUBLE PRECISION TABLE1,TABLE2 DIMENSION TABLE1(5,10),TABLE2(5,10),B(:,:) POINTER A可以比较什么两种表示方法,在说明了同样的意思的前提下,把属性说明附加在数据类型说明语句当中,比每一种属性单独一个语句加以说明要简洁自然得多。7.2.3 复型COMPLEX语句声明了复型
19、数据对象的名称,同时也可以附加种别参数以及其他属性。如果给出种别选择符,即说明该复型数据的表示方法。说明复型数据类型的句法为:COMPLEX (KIND = kind-value ) , attribute-list : entry-list【例7-8】 下面是各种形式的复型数据对象声明语句:COMPLEX chCOMPLEX (KIND=4),PRIVATE : zz, yy !等价于COMPLEX*8 zz, yyCOMPLEX(8) ax, by ! 等价于COMPLEX*16 ax, byCOMPLEX (kind(4) y(10)complex (kind=8) x, z(10)7.
20、2.4 逻辑型LOGICA语句声明了逻辑型数据对象的名称,同时也可以附加种别参数以及其他属性。如果给出种别选择符,即说明该逻辑型数据的表示方法。说明逻辑型数据类型的句法为:LOGICAL (KIND = kind-value ) , attribute-list : entry-list【例7-9】 下面是各种形式的主要说明逻辑型对象的声明语句:LOGICAL, ALLOCATABLE : flag1, flag2LOGICAL (KIND = byte), SAVE : doit, dont【例7-10】 下面是各种形式的主要说明对象的属性的声明语句:LOGICAL flag1, flag2
21、LOGICAL (KIND = byte) doit, dontALLOCATABLE flag1, flag2SAVE doit, dont7.2.5 字符型CHARACTER语句声明了字符型数据对象的名称,同时也可以附加种别参数以及其他属性。如果给出字符选择符,即说明该字符型数据的最大字符长度。说明字符型数据类型的句法为:CHARACTER character-selector , attribute-list : entry-list其中的字符选择符(character-selector)的句法形式(R507)可以为如下几种:length-selector(LEN =length-val
22、ue , KIND = kind-value )(length-value , KIND = kind-value )(KIND = kind-value ,LEN =length-value )其中长度选择符(length-selector)的句法形式(R508)可以是: (LEN = length-value) * character-length ,其中字符长度(LEN)(R509)可以是: (length-value) scalar-integer-literal-constant其中长度值(length-value)(R510)可以是: specification-expressio
23、n *在上面的类型说明当中,使用星号*来标志字符长度的方式属于过时的方式,不过不是指在数据项里面使用的星号*。字符型数据对象类型声明语句的一般规则如下: 只有在没有使用双冒号的情况下,在长度选择符里才可以使用逗号。 字符型数据对象的字符长度在一定的情形下,是可以发生动态变化的,即当一个字符型数据的声明语句出现在一个过程或者是过程界面当中,同时该数据对象又不是某个派生数据对象的成员,那么它的字符长度可以使用非常量表达式,该表达式的具体取值只有当访问该过程时才被确定,并且当该过程的运行时,表达式里变量的变化并不影响字符长度值。这样一种数据对象如果不属于哑元,则属于自动数据对象的范畴。 字符长度的说
24、明有三种情形: 首先在数据项或数据项列的成员里给出字符长度; 如果没有上面的长度说明,则在数据类型说明部分给出命名字符数据项或派生类型定义当中的字符成员的字符选择符,用来给出长度属性; 如果一个字符型数据既没有使用字符选择符,也没有使用字符长度来说明其长度,那么默认的字符长度为1。 如果长度参数取负值,那么相应的字符项长度为0。 给定了字符长度的标量整型文字常量不能再附加任何种别参数,否则在固定源码形式里面就会导致歧义。 采用带星号*的长度说明只能使用于以下几种情形:可以应用于过程的哑元,当过程被调用时,哑元就被赋予相应实元的长度;可以用于声明命名常量,这时它的长度是一个常量值;可以用于声明一
25、个外部函数的结果变量的长度。任何调用该函数的作用域单元如果使用带星号的长度说明,就意味着主程序可以访问该声明。当函数被调用的时候,结果变量的长度的取值由引用该函数的程序单元里面的相应声明语句决定。本规则暗示了在IMPLICIT语句当中不能使用带星号*的长度说明方式。 如果一个函数属于内部函数或模块函数,或者该函数的值为数组,指针或递归形式,那么该函数名不能使用带星号*的长度声明。 字符值语句函数或字符型语句函数哑元的长度必须是整型常量表达式。【例7-11】 下面是各种形式的主要说明字符型数据对象的声明语句:CHARACTER (LEN=25,KIND=GREEK),DIMENSION(11):
26、Z1CHARACTER (LEN=20,KIND=KANJI),SAVE:GREETING(2)CHARACTER (10):QUESTION=“WHERE?”CHARACTER (LEN=*,KIND=CHINESE),PARAMETER:MESSAGE = &“简朴是语言的一种美德”CHARACTER (*),INTENT(IN):SCHOOL, HOMECHARACTER *3, SAVE : COMPONENT_1, LONGER(9) *20, COMPONENT_2CHARACTER : RESULT = “PASS”例7-12:下面是各种形式的主要说明字符型数据的属性的声明语句:
27、CHARACTER (70)PROJECTCHARACTER (LEN=30, KIND=GERMAN)TRANSFORMATIONCHARACTER (LEN=25,KIND=GREEK)Z1CHARACTER (LEN=20,KIND=KANJI)GREETING(2)CHARACTER (10)QUESTIONCHARACTER (*)SCHOOL, HOMECHARACTER *3 COMPONENT_1, LONGER(9) *20, COMPONENT_2CHARACTER RESULT SAVE GREETING(2)INTENT(IN)SCHOOL, HOMEDATA QUES
28、TION /“WHERE?”/CHARACTER (*)MESSAGEPARAMETER( MESSAGE = & “简朴是语言的一种美德”)7.2.6 派生类型TYPE语句声明了用户派生数据类型对象的名称,派生类型的名称写在紧跟TYPE后面的一对括号当中,声明派生类型的数据对象的一般句法为:TYPE(type-name) , attribute-list : entry-list派生类型声明语句的一般规则如下: 如果一个派生类型对象是私有的话,就不能附加PUBLIC属性。 结构构造器必须用来初始化派生类型数据对象,结构构造器里的表达式必须是初始化表达式。 如果需要声明的派生数据对象是一个函数
29、的结果,那么它就可以在FUNCTION语句当中予以说明。【例7-13】 下面是各种形式的主要说明派生数据对象的声明语句: TYPE(SAMPLE),DIMENSION( :),ALLOCATABLE:STOVE TYPE(STUDENT),SAVE:GRAD(5) TYPE(HOMEWORK),SAVE:QUESTION,TAPE,WORD_SHEET【例7-14】 下面是各种形式的主要说明派生数据对象的属性的声明语句: TYPE(SAMPLE)STOVE TYPE(STUDENT)GRAD(5) TYPE(HOMEWORK)QUESTION,TAPE,WORD_SHEET DIMENSION
30、 STOVE( :)ALLOCATABLE STOVE SAVE GRAD(5), QUESTION,TAPE,WORD_SHEET注意上面这两种说明方法里面标点的不同用法。7.3 隐式类型描述法 当初FORTRAN使用隐式类型声明方法,是与语言的简朴形态相适应的,在硬件资源相对紧缺的时代,简朴也能成为语言的一种美德,不过如果到了硬件资源相对富余的今天,还吝啬于增加几个关键词和几条声明语句,就会显得很落伍了,所以后来就增加了更为接近自然语言的声明语句,不过,为了缅怀FORTRAN语言作为祖母级高级语言的荣耀,隐式类型声明方式还是保留下来了,甚至默认为总是起作用,除非首先声明了IMPLICIT
31、NONE语句。当然,只要你乐意使用,这种类型声明方式在某些情况下,还是非常方便简明的。隐式类型声明方法的出发点,是考虑到任何需要加以类型声明的对象,如变量,命名常量,函数等,都需要一个名称来指称,那么就可以把它的类型这个信息负载在它的名称上,最简单的约定,就是让名称的第一个字母来标记它的类型,例如在默认的情形下:REAL: A B C D E F G H INTEGER: I J K L M NREAL: O P Q R S T U V W X Y Z可以发现,上面对字母的默认分配并不是很难记忆,FORTRAN沿用了数学里的很多习惯,这里使用I,J,K,L,M,N来表述整数,就是一个明显的数学
32、习惯。除了上面默认的首字母隐式类型法则,隐式类型声明方法还有很灵活的一面,即利用IMPLICIT语句来自定义字母分配模式,一般的IMPLICIT语句的句法形式(R541)有2种,分别行使不同的功能: IMPLICIT type-specification(letter-specification-list) IMPLICIT NONE其中的字母分配说明列表的句法形式(R543)为: letter-letter这里IMPLICIT后面的字母分配表定义可以完全是自由定义,并且只是在该语句的作用域内有效,而任何名称在它的作用域内只要是没有专门的类型声明语句,也没有IMPLICIT语句,那么它就遵循上
33、面的默认首字母隐式类型法则。隐式类型的一般规则如下: 如果要使用IMPLICIT NONE语句,那么它必须放置在任何PARAMETER语句之前,并且在其作用域内,再也不能出现其他IMPLICIT语句。 IMPLICIT语句当中出现的表述字母范围的letter-letter,左边的字母绝对不能是右边字母的按照字母表顺序的后面的字母。 letter-letter的字母之间为减号,而非下划线,表示按照字母表顺序从左边字母到右边字母的所有字母。 在一个作用域里面的IMPLICIT语句里面,同一个字母不能出现在字母分配说明列表里面的不同项里,例如作为单个字母出现了,又同时处于另一个字母范围之中,或同时处
34、于2个不同的字母范围里面。 IMPLICIT语句同样可以用来为派生数据类型分配首字母作为类型标记。默认的首字母隐式类型法则与IMPLICIT语句之间的关系值得特别加以注意。例如给出约定:IMPLICIT COMPLEX(E-G,W-Z)然后在该语句的作用域里再也没有其他IMPLICIT语句,也没有类型声明语句,那么在该作用域内具有不属于(E-G,W-Z)这个范围的首字母的变量,将遵循默认首字母分配表,即首字母在范围(A-D,H,O-V)内的变量属于实型,而首字母在范围(I-N)内的变量属于整型。IMPLICIT NONE可以用来检查名称的错误拼写,因为如果不加以这个语句的话,即使错误拼写的名称
35、,也会被看成遵循首字母隐式类型声明方法的具有确定数据类型的变量,从而能够通过语法检查,反之使用该语句,就可以避免这种误解。【例7-15】 下面的IMPLICIT语句都是合法语句: IMPLICIT CHARACTER*30(B,T),COMPLEX(W-Z) IMPLICIT LOGICAL(KIND=BIT)(Q) IMPLICIT REAL(QUAD)(X-Z) IMPLICIT TYPE(NUMBER)(A-E) IMPLICIT TYPE(ARTICAL)(A,V),CHARACTER*100(B)【例7-16】 下面的IMPLICIT语句都是非法语句:IMPLICIT CHARACT
36、ER*30(B,T),COMPLEX(Z -W)!W应该放置在Z 之!前。 IMPLICIT LOGICAL(KIND=BIT)(Q),REAL(QUAD)(P-T)!Q同时表!示2种类型。 IMPLICIT TYPE(ARTICAL)(A-H),CHARACTER*100(B,Q)!B同时表!示2种类型。使用隐式类型声明在一个嵌套作用域里面所导致的变量作用域混乱问题在有关作用域之间通讯时再讨论。7.4 数组属性数组的概念来源于数学的向量概念,最大的特点就是数组的各个分量必须是同一种数据类型,同样的种别参数,具有同样的属性,因此数组本身作为一个数据对象,最主要的属性就只剩下它的维度,也就是它的
37、秩。作为一个变量的数组可以有多种形式,除了它的分量可以发生变化之外,它的维度也可以发生变化,有3种情形需要数组的维度不予固定: 在程序运行当中,数组所占据的存储空间不是固定的,而是可重新分配的,这意味着该数组必定具有ALLOCATABLE属性; 该数组被赋予指针的属性,使得它的维度无法预先固定下来; 该数组本身就是一个哑元,它的维度依赖于别的变量对它的赋值情况。因此数组本身形状的说明出现了4种形式,而数组所特有的属性,主要就是DIMENSION和ALLOCATABLE,下面分小节予以说明。7.3.1 数组描述的4种形式数组描述的4种形式的句法形式(R513)为:explicit-shape-s
38、pecification-listdeferred-shape-specification-listassumed- shape-specification-listassumed-size-specification这四种形式分别用来描述数组在程序当中出现的四种可能情形: 首先是最基本的显形数组(explicit-shape arrays),即在定义数组的时候就已经给出它的形状; 当一个数组具有指针属性,或具有可分配属性时,它的形状就没法预先给定,需要在程序运行过程当中通过指针或分配过程予以确定,这时就需要使用待定形数组(deferred-shape arrays)的形式来加以描述; 当数组
39、本身属于哑元时,它的形状就需要实元来赋予,这样就需要使用哑形数组(assumed- shape arrays)的形式来加以描述; 如果实元赋予一个作为哑元的数组时,只是决定它的尺度,而没有给定其他形状要素,那么就需要使用哑尺度数组(assumed-size arrays)的形式来加以描述。下面我们将分节说明这四种数组的描述方式。数组的描述的一般规则如下: 按照FORTRAN标准,数组的秩至少可以达到7,尽管一般应用环境里,秩为2或3是最常见的,但是对于一些特定的计算问题,可能需要用到非常高的维度的数组,所以一般的FORTRAN编译器都能支持远大于7的秩。 一个标量的秩为0。 待定形数组必定或者
40、具有POINTER的属性,或者具有ALLOCATABLE的属性。 哑形数组和哑尺度数组必定属于哑元。 必须注意待定形数组和哑形数组的表示形式可能出现雷同的时候,即都是使用一个冒号表示。7.3.2 显形数组顾名思义,所谓显形数组就是对于数组的每一个维度都给出了具体的上下界,每个维度的显形说明的句法形式(R514)如下: low-bound : upper-bound其中的上界(upper-bound)和下界(low-bound)为说明表达式。参见表达式。显形数组的一般规则如下: 显形数组的说明列表里所给出的上下界对的数目必须与该数组的维度数目一致。 如果下界被省略了,则表明取默认值1。 上下界可
41、以是正整数,也可以是负整数,还可以是0。 数组的下标范围就是在上下界之间,包括上下界本身的所有整数集合,并且上界不能小于下界,如果出现这种情况,表明下标范围为空集,或者说其相应维度的宽度为0,而且数组的尺度也为0。 如果上下界是以表达式的形式出现,那么可能包含变量,使得上下界的具体取值在数组所处的过程运行当中发生变化,这时,该数组必定是一个哑元,或者是一个函数结果,或者是一个动态数组。【例7-17】 下面是主要说明数据项的声明语句: INTEGER X(20:30,5,-10:40) . SUBROUTINE AAA(I,J,K) REAL,DIMENSION(10:I+2,J):K .【例7
42、-18】 下面是主要说明属性的声明语句: INTEGER X(20:30,5,-10:40) . SUBROUTINE AAA(I,J,K) REAL KDIMENSION K(10:I+2,J) .7.3.3 待定形数组待定形数组用来表示具有指针属性和可分配属性的数组。 对于指针数组来说,数组的每个维度的宽度是在指针被分配或指针赋值语句被执行之后才给定的; 对于可分配数组来说,它的上下界只是在被分配之后才给出。因此对于这种数组的形状说明,只能使用一个冒号,即如下的句法形式(R518): : 待定形数组的一般规则如下: 待定形数组的秩等于它的说明列表当中出现的冒号的数目。 当待定形数组完成存储
43、分配之后,它的上下界在ALLOCATE语句当中被确定。 对一个指针数组的目标数组的每个维度执行固有函数LBOUND,就能得到指针数组的相应维度的下界;同样的,对一个指针数组的目标数组的每个维度执行固有函数UBOUND,就能得到指针数组的相应维度的上界。因此, 如果上下界是由指针的分配决定,那么该数组的形状就可以由用户来指定; 如果上下界是由指针的赋值决定,那么该数组的形状就可以有二种情形: 如果指针目标是一个命名全数组,那么上下界就由该数组的声明决定,或者在该数组被分配之后给出; 如果指针目标是一个数组片断,那么它的下界为1,而上界为所处维度的宽度。 如果指针数组或可分配的上下界里面包含变量,
44、那么当变量在随后有了重定义与去定义的情形的话,上下界不受这种变化的影响。【例7-19】 下面是主要说明数据项的声明语句: REAL,POINTER:A( : , : ),B( : , : ) REAL,ALLOCATABLE:A( : , : )【例7-20】 下面是主要说明属性的声明语句: REAL A( : , : ),B( : , : ) POINTER A,BALLOCATABLE A7.3.4 哑形数组所谓哑形数组,就是一个哑元,它的形状只有在与一个实元相结合时才能定下来,哑形数组的说明句法(R517)为: low-bound :即只是可选地给出一个下界,然后就是一个冒号,下界阙如,
45、表示未定。哑形数组的一般规则如下: 哑形数组的说明列表当中出现的冒号的个数,就等于该数组的秩。 下界或者明确给出,或者省略,表示下界取默认值1。 上界等于数组在相应维度上的宽度加下界值减1。 哑形数组不能具有POINTER或ALLOCATABLE这二种属性。 未结合指针数组的尺度,界和形状都是未定义的,这样一个数组的任何部分都不能被引用或定义,不过这样的数组可以作为固有查询函数的变量出现,从而可以查询变量状态,数据类型性质,类型参数,或者结合状态。【例7-21】 下面是主要说明数据项的声明语句: SUBROUTING AAA(X,Y,Z) REAL,DIMENSION(5:,:):A REAL
46、,INTENT(IN):X( :),Y(5:)【例7-22】 下面是主要说明属性的声明语句: SUBROUTING AAA(X,Y,Z) REAL X( :),Y(5:),ZDIMENSION A(5:,:) INTENT(IN)X,Y .7.3.5 哑尺度数组一个哑尺度数组就是一个哑元,而它的尺度由与它相关联的实元设定,因此在声明哑尺度数组时,就给定了它的尺度,即秩,宽度和界(最后一个维度的上界和宽度除外)。对于哑尺度数组和实元之间的关联有如下规则: 二者具有相同的初始数组元素。 后继数组元素是按照存储顺序排列的。 哑元的声明就需要给出数组的秩,所有维度的下界,以及除了最后一个维度之外的所有
47、的上界与宽度。 实元的尺度哑元的尺度。哑尺度数组的最后一个维度的上界不能给出,因此使用星号(*)表示。哑尺度数组的句法形式(R519)为: explicit-shape-list, low-bound: *可见,哑尺度数组与显形数组在形式上的主要差别就是最后一个维度的上界有待给出。哑尺度数组的一般规则如下: 哑尺度数组的秩就是它的显形数组的说明列表当中的说明数目加1。 哑尺度数组的尺度根据以下途径来决定: 如果与哑元相关联的实元是非默认字符类型的任意其他类型数组,那么哑元的尺度就是实元的尺度。 如果与哑元相关联的实元是非默认字符类型的任意其他类型数组元素,并且它的下标顺序值是一个尺度为x的数组
48、当中的v,那么该哑元的尺度为x-v+1。 如果与哑元相关联的实元属于默认字符类型数组,或者属于默认字符型数组元,或者属于默认字符型数组元素子串,假设它开始于一个以c作为字符存储单位的数组的第t个字符存储单位,那么哑元的尺度为:MAX(INT(c-t+1)/e),0)其中e是哑字符数组里的元素的长度。 设数组的秩为r,那么前r-1维的界都由相应的显形数组说明给定,最后一个维度的下界则由声明中给出的下界给定,如果没有给出,则取默认值1。 如果界的表达式里面包含变量,那么当相应过程执行时,就会导致表达式取值发变化,但是当变量在随后如果是有了重定义与去定义的情形的话,上下界则不受这种变化的影响。 函数
49、结果不能成为哑尺度数组。 除了以下两种情形,哑尺度数组不能作为全数组引用: 在过程引用当中没有要求实元的形状; 引用到固有函数LBOUND。【例7-23】 下面是主要说明数据项的声明语句: SUBROUTING PRO(A,B,C) REAL,DIMENSION(A,*):B REAL C(100,20,*) .【例7-24】 下面是主要说明属性的声明语句: SUBROUTING PRO(A,B,C) REAL B, C(100,20,*) DIMENSION B(A,*): .7.3.6 数组的四种声明形式的兼容性数组的四种声明形式可以在程序里扮演的脚色有各种限制,也就是说具有不同的语法作用
50、。下面的表7-2给出这四种形式与不同语法单位的兼容性限制:表7-2数组的四种声明形式的兼容性数组声明的形式数组的语法单位显形数组待定形数组哑形数组哑尺度数组表达式的主项可可可否下标向量可可可否哑元可可可可实元可可可可等价对象可否否否公用对象可可否否名称列表对象可否否否保留对象可可否否初始化数据对象可否否否I/O列表项可可可否格式可可可否内部文件可可可否分配对象否可否否指针赋值语句里的指针对象否可否否指针赋值语句里的目标对象可可可否 7.3.7 DIMENSION属性和DIMENSION语句数组的维度除了可以在数组声明语句当中,通过数组名称的说明来给出之外,还可以使用DIMENSION属性语句来
51、给出,实际上,DIMENSION语句属于FORTRAN早期标准的遗留物,现在既可作为单独的属性语句出现,也可以附加在数据声明语句里面。附加DIMENSION属性的数据类型声明语句的句法形式为: type-specification,DIMENSION(array-specification) ,attribute-list:& entity-list可以跟在DIMENSION属性语句后面的其他属性有: initialization ALLOCATABLE INTENT OPTIONAL PARAMETER POINTER PRIVATE PUBLIC SAVE TARGET另外,数组说明可以使
52、用一个数组名称,然后后面附加其他语句来声明一个数组,这些语句可以是DIMENSION语句,类型声明,ALLOCATABLE,POINTER,TARGET,COMMON等语句。如果以说明DIMENSION属性为主给出数组定义,那么可以采用如下的句法形式(R526): DIMENSION : array-name(array-specification)& ,array-name(array-specification) 【例7-25】 下面是主要说明数据项的声明语句: REAL,ALLOCATABLE,TARGET:X( :,:) REAL,DIMENSION(30),TARGET,SAVE:M
53、ETER【例7-26】 下面是主要说明属性的声明语句: REAL X( :,:),METER DIMENSION METER(30) TARGET X,METERALLOCATABLE XSAVE METER【例7-27】 下面是在其他声明语句当中使用数组说明的例子: REAL X,METER TARGET X,METER(30)ALLOCATABLE X( :,:)SAVE METER【例7-28】 下面是在COMMON语句当中使用数组说明的例子: COMMON / MOTION / TIME(30),SPACE(1000,1000,1000)7.3.8 ALLOCATABLE属性和ALLO
54、CATABLE语句一个数组可分配是指它的界只有在执行ALLOCATE语句之后才能确定。这样一个数组必定是一个待定形数组。ALLOCATABLE属性只是针对数组而言才成立。一个具有ALLOCATABLE属性的数组的类型声明的句法形式为:type-specification,ALLOCATABLE ,attribute-list:entity-list能与ALLOCATABLE兼容的属性有:DIMENSION(deferred-shape- specification-list)PRIVATEPUBLICSAVETARGET单独的ALLOCATABLE属性语句的句法形式(R527)为: ALLOC
55、ATABLE: array-name (deferred-shape- specification-list)& ,array-name (deferred-shape- specification-list) ALLOCATABLE属性声明的一般规则如下: 具有ALLOCATABLE属性的数组就不能是哑元或函数结果。 如果给定具有ALLOCATABLE属性的数组,再在任何位置给出具有DIMENSION属性,都必须使用单独的冒号来表示为待定形数组。【例7-29】 下面是主要说明数据项的例子: REAL,ALLOCATABLE,SAVE:X(:,:) INTEGER,ALLOCATABLE,DI
56、MENSION(:):Y【例7-30】 下面是主要说明属性的例子: REAL X(:,:) INTEGER YDIMENSION Y(:)ALLOCATABLE X,YSAVE X7.4 指针属性一般说来,我们给一个数据对象附加一种属性,总是意味着给该数据对象增加某种它本来没有的性质,但是指针(POINTER)属性则不然,当我们把POINTER属性附加给某个数据对象,实际上是把该数据对象本来具有的存储空间给拿掉了。由于我们要引用一个数据对象,前提必然是已经确定了该数据对象的存储空间,才能准确地加以访问,那么显然,对于一个具有POINTER属性的数据对象,既然它不具有了初始的存储空间,也就无法加
57、以引用,除非再给该数据对象关联上一个存储空间。给POINTER对象关联到一个存储空间,可以通过如下方法: 使用ALLOCATE语句为POINTER对象创造一个新的存储空间; 使用指针赋值语句使得POINTER对象从另外一个具有存储空间的数据对象那里借用其存储空间,那个被借用存储空间的数据对象称为指针的目标。目标数据对象在程序运行时是可以发生变化的,它有两种来源: 赋予了TARGET属性的数据对象,或者它的某个部分; 指针通过分配而创造出来的新的数据对象,或者它的某个部分。指针可以被关联到另外一个指针的目标,或者目标的某个部分。对于一个数组来说,要使得它成为某个指针的目标,除了具有ALLOCAT
58、ABLE属性之外,还必须具有TARGET属性。在一个程序里,最初建立一个指针对象之后,还必须对它进行初始化,也就是定义它的初始状态(参见7.5),然后才可以使用固有函数ASSOCIATED来查询指针的状态,否则,该指针既不能被引用,也不能出现在DEALLOCATE语句当中。所谓指针的经过定义了的状态有两种:关联与去关联。 通过ALLOCATE与指针赋值语句,可以使得指针具有关联状态; 通过DEALLOCATE或者NULLIFY语句,或者让指针赋值给另外一个本来处于去关联状态的指针,可以使得指针具有去关联状态。一个指针无论是处于关联状态还是去关联状态,总之是已经被定义的状态,因此可以使用固有函数
59、ASSOCIATED来查询它是否处于关联状态。实际上,对于指针我们还可以看成是一个描述符,这个描述符所占据的空间里存储了有关它所指称的对象的数据类型,种别参数,秩,宽度,以及目标的位置等这类信息。因此一个实型标量对象指针必然和一个派生类型的数组指针具有完全不同的存储空间单位,那么给出一个指针必然无法预先给定它的存储单位,当我们要在一个公用块里声明指针属性的时候,就相当于给出存储的描述符,因此每当我们声明一个包含指针的公用块时,都必定指定相同的存储单位序列。7.4.1 POINTER属性和POINTER语句附加了POINTER属性说明的类型声明的句法形式为:type-specification,
60、POINTER ,attribute-list:entity-list可以与POINTER兼容的其他属性包括: initializationDIMENSION(deferred-shape- specification-list) OPTIONAL PRIVATE PUBLIC SAVE单独的POINTER语句也可以用来声明一个指针对象,它的句法形式(R528)为: POINTER : object-name (deferred-shape- specification-list)& ,object-name (deferred-shape- specification-list) 指针声明的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 专项购买服务合同范本
- 公司聘请物业合同范本
- 2025年安徽道路货运驾驶员从业资格证考试题库
- 前台用工合同范本
- 办公桌椅合同范本
- 中标平台合同范本
- 中铁高速公路合同范本
- 加气砌块合同范本
- 劳务医院合同范本
- 公司车辆供货合同范例
- 2025年湖南铁路科技职业技术学院单招职业技能测试题库参考答案
- 酒店长包房租赁协议书范本
- 2025年几内亚水泥厂项目投资可行性报告
- 【道法】开学第一课 课件-2024-2025学年统编版道德与法治七年级下册
- 口腔门诊分诊流程
- 提高设备基础预埋螺栓一次安装合格率
- 2025年春新外研版(三起)英语三年级下册课件 Unit2第1课时Startup
- 2025年上半年天津市宁河区事业单位招聘12人重点基础提升(共500题)附带答案详解-1
- 2024年科技节小学科普知识竞赛题及答案(共100题)
- 心肺复苏课件
- 中华民族共同体概论专家讲座第一讲中华民族共同体基础理论
评论
0/150
提交评论