- 第一章 Fortran 语言程序设计初步
- 第二章 改变程序流程
- 第三章 循环结构
- 第四章 数据结构
- 第五章 数组
- 第六章 过程和模块
- 第七章 输入输出和文件
5.1.2 数组类型
a) 显式形状(Explicit-shape) 数组
这种数组指定了所有特征:固定的秩、每一维的长度和形状。其中下界是可以忽略的。它的一般形式是:([下界:]上界[,[下界:]上界]…)
例:INTEGER M(10,10,10),K(-3:6,4:13,0:9)
维界可以是常数或变量。在过程(函数和子程序) 中,数组的上界和下界可以由变量或表达式指定。使用变量或表达式的数组是自动数组和可调数组。
b) 自动(Automatic) 数组
自动数组是显形数组的一种,它是过程中的局域变量,自动数组必须在过程中加以声明,并且它的上下界是不定的表达式。在调用过程时,上下界通过变量或表达式求出。过程中其后的变量或表达式值的变化不会对数组的上下界产生影响。
例:SUBROUTINE EXAMPLE(N,R1,R2)
DIMENSION A(N,5),B(10*N)
……
N=IFIX(R1)+IFIX(R2)
此例中的 A 和 B 都是自动数组。子程序被调用时,数组 A 和 B 的上界通过传入的变量 N 来确定,而以后 N 的值的变化对 A 和 B 的大小不会有影响。
例:SUBROUTINE SUB1(A,B)
INTEGER A,B,LOWER
COMMON/BOUND/LOWER
……
INTEGER AUTO_ARRAY1(B)
INTEGER AUTO_ARRAY2(LOWER:B)
INTEGER AUTO_ARRAY3(20,B*A/2)
……
END SUBROUTINE
c) 可调(Adjustable) 数组
可调数组也是显形数组的一种,它是过程的一个哑元,至少有一个维界不是常数,这个维界当过程被调用时才被确定。其维界表达式中的变量是哑元,或者是通过 COMMON 语句中传递的常量。注意多维可调数组的维界表达式必须与调用时的维界相符。
例:DIMENSION A1(10,35),A2(3,56)
……
SUM1=THE_SUM(A1,10,35)
SUM2=THE_SUM(A2,3,56)
END
FUNCTION THE_SUM(A,M,N)
DIMENSION A(M,N)
SUMX=0.0
DO J=1,N
DO I=1,M
SUMX=SUMX+A(I,J)
END DO
END DO
THE_SUM=SUMX
END FUNCTION
其中哑元 M,N 控制着可调数组的大小。下例说明了可调数组的维界 X(-4:4,5) 在调用过程时被确定后,过程内部对维界参数的赋值不会改变维界值。
例:DIMENSION ARRAY(9,5)
L=9
M=5
CALL SUB(ARRAY,L,M)
END
SUBROUTINE SUB(X,I,J)
DIMENSION X(-I/2:I/2,J)
X(I/2,J)=999
J=1
I=2
END
a) 假定形状(Assumed-shape) 数组
这种数组是在过程中的哑元,它从实际传递过来的数组获得形状参数。假定形状数组的秩由冒号的个数决定。它的一般形式是:([下界]:[,[下界]:]...)。如果不指定下界,则默认值为 1。上界值=过程调用时实参数组对应维的长度+下界值-1。注意它与可调数组的区别在于,可调数组属于显型数组(必须指定上界)的范围,而假定形状数组的上界是不能指定的。
例:SUBROUTINE ASSUMED(A)
REAL A(:,:,:)
此时数组 A 的秩为 3,但每一维的长度待定。当过程被调用时 A 将从传递到过程的数组获得形状:
REAL X(4,7,9)
CALL ASSUMED(X)
于是 A 获得了数组维界(4,7,9),实际数组和假定形状数组的值必须相同。如果上面过程中数组声明了 A(3:,0:,-2:),以哑元 X(4,7,9) 调用过程时,数组 A 的实际维界是 A(3:6,0:6,-2:6)。
应用假定形状数组为哑元的过程时必须有显式的接口 INTERFACE 语句。
例:INTERFACE
SUBROUTINE SUB(M)
INTEGER M(:,1:,5:)
END SUBROUTINE
END INTERFACE
INTEGER L(20,5:25,10)
CALL SUB(L)
在此例中数组 M 的维界是(1:20,1:21,5:14)。
b) 假定大小(Assumed-size) 数组
这种数组是在过程中的哑元,它从实际传递过来的数组获得数组大小。除了最后一维的上界以外,其它所有特征(秩,长度和维界)都必须指定。声明一个假定大小数组时,最后一个的上界用星号*表示。它的一般形式是:([显型维界,][显型维界,]...[下界:]*)。
例:SUBROUTINE ASSUME(A)
REAL A(2,2,*)
假定大小数组的秩和形状可以和实际传入的数组不同,传入的数组只确定它的大小。实际数组的元素按列传递给假定大小数组,假定大小数组也按列接收。接受的过程中假定大小数组的最后一维的长度会改变来接受所有传递进来的数组元素,于是最终给出数组的大小。如上例子中的 ASSUME 子程序,如果以数组 X 为哑元来调用的话,
REAL X(7)
CALL ASSUME(X)
则数组 X 的元素与数组 A 的对应顺序是:
X(1):A(1,1,1)
X(2):A(2,1,1)
X(3):A(1,2,1)
X(4):A(2,2,1)
X(5):A(1,1,2)
X(6):A(2,1,2)
X(7):A(1,2,2)
其中数组 A 的最后一维没有必要成为完整的维,所以数组 A 始终没有确定的形状。因为假定大小数组没有形状,所以这样的数组不能仅仅通过名称来向其它过程传递。
假定大小数组可以分解成确定的数组片段。如上例中的数组 A,可分为三个片段:A(1:2,1:2,1) 和 A(1:2,1,2) 以及 A(1,2,2)。
假定大小数组的秩是完全确定的维数+1。上例中数组 A 的秩为 3,尽管 A 的第三维不是完整的。
c) 延迟形状(Deferred-shape) 数组
可分配数组必须以延迟形状的形式来声明。它每一维的长度只有在分配数组才被确定。声明迟形数组时,秩由冒号确定,但长度是未知的。
例:REAL,ALLOCATABLE:: A(:,:,:)
INTEGER,ALLOCATABLE,TARGET:: K(:)
可分配数组可由下列方式声明:使用 ALLOCATABLE 语句、DIMENSION 语句、TARGET 语句或在类型声明中使用 ALLOCATABLE 属性。如果迟形数组以 DIMENSION 语句或 TARGET 语句声明,则在其它语句中必须给出 ALLOCATABLE 属性。
在迟形数组的大小、形状和维界没有确定之前,其任何部分都不能被引用,可分配数组的大小、形状和维界在 ALLOCATE 语句执行时才被确定。 [e_512_01.f90]
例:INTEGER,ALLOCATABLE:: A(:,:)
REAL,ALLOCATABLE,TARGET:: B(:,:),C(:)
ALLOCATE(A(2,3),C(5),B(SIZE(C),12))
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论