您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > FORTRAN数组介绍大全
§6数组§6.1数组的定义与操作§6.2动态数组§6.3数组在函数和子程序中的应用§6.4数组的应用举例§6.1数组的定义与操作数组:相同类型数据组成的有序的有限集合数组必须先定义后使用。定义数组时,要对数组的名称、类型、数组的维数和元素的数量加以说明。用类型说明结合DIMENSION属性进行定义:类型,dimension(维数说明[,维数说明])::数组名[,数组名]§6.1.1数组的定义维数说明:由下标界限说明组成,有几个下标界限说明就表示数组是几维的。多于一维的数组称多维数组,下标界限说明之间用逗号(,)分隔。下标界限说明的写法:下标下限:下标上界下标界限为整数,上界必须大于下界下标下界为1时可以连同后面的冒号一起省略;但是,上界是不可省略的。定义数组时,下标界限必须为整型常量。例:INTEGER,DIMENSION(-2:10)::P定义一维整数组P,下标从-2到10,13个元素。例:DIMENSIONA(12),IW(4,5)定义一维实型数组A,下标从1到12,12个元素;定义二维整型数组IW,4行5列,20个元素。例:real,dimension(3,4)::b,m(-5:10)定义二维实型数组B,3行4列,12个元素;定义一维实型数组M,下标从-5到10,16个元素。例:characterc(100)*20定义一维字符数组C,有100个字符串,每个可容纳20个字符§6.1.2数组的逻辑结构与存储结构一维数组:数列、向量二维数组:矩阵、行列式、表格三维数组:帐簿对更多维数的数组,可以从概念上理解。在学习程序设计语言时,一般只要求熟练掌握二维数组的应用,作为理解和应用多维数组的基础。数组元素在内存中连续存放,下标数值小的排在前面。存储多维数组时,下标变化速度依次为第一个,第二个…例:A(10),依次存储A(1),A(2),A(3),…A(10)B(8,9),依次存B(1,1),B(2,1),…B(8,1),B(1,2),B(2,2),…B(8,2),…………………….B(1,9),B(2,9),…B(8,9)特别提示:二维数组是按列存储的。用数组名(下标[,下标])指定所要引用的数组元素。例:a(12),B5(3,6),c3b4(I,J,K)数组元素的下标可以是算术表达式,系统计算此表达式的值并自动取整。表达式中所涉及到的不是常量的量必须要先行算出。例:a(I+1),b5(b5(3)+a(2))例:c3b4(I,I+5,c3b4(a(b5(c3b4(1,4,2),6)),3,2))§6.1.3数组元素的引用必须确保数组元素的下标的值不超过下标界限。如果下标越界,系统一般会对存储于数组之前(后)的存储单元进行操作(引用或者赋值),导致错误。如果作为数组元素的下标的算术表达式中存在没有赋值的变量,系统一般自动将它按零处理,可能会导致计算结果不正确,或者不稳定(时对时错)。这类错误很难发现,是许多程序存在bug的原因。数组元素的下标表达式过于复杂时,最好先行算出,最好不要书写过于复杂的语句和表达式。§6.1.4数组的输入与输出数组必须先定义后使用,本节讨论中提到的数组假定已经定义如下:DIMENSIONA(10),M(12),D(5,6)允许用数组名来I/O整个数组例:READ(*,*)A,M,DWRITE(*,*)A,D多维数组I/O时,按其元素在内存中存储的顺序依次I/O各元素,遵守的原则是:最左边的下标变化最快。特别提示:二维数组是按列存储的,在输入/输出时也按列进行。在程序中可以输入/输出指定的元素,作为特例,可用DO循环对数组全体元素或部分元素进行输入/输出。DoI=1,5doj=1,6read*,d(I,j)enddoEnddo用DO循环对数组进行输入/输出不方便,为此,提供了针对I/O的隐含DO循环方式。例:read(*,*)(A(I),I=4,10,2)read(*,*)(M(K),K=1,12)WRITE(*,*)((D(L,N),N=1,6),L=1,5)隐含DO循环方式输出/输入多维数组时要用到多重循环,注意其书写方式。§6.1.5数组的操作数组赋值:可以给所有元素赋同一个值例:DIMENSIONA(10),M(12),D(5,6)A=1.2;M=3;D=4.5数组构造器:(/取值列表/)取值列表:标量、隐DO表、向量。隐DO表和向量整体作为一个标量。标量之间用逗号。数组构造器可给多维数组的某一维赋值:Real,Dimension(2,3)::A,BA(1,:)=(/1,2,3/)!给第1行赋值A(2,:)=(/4,5,6/)!第2行§6.1.5数组的操作通过Reshape()函数可以把数组构造器的数据赋给某种形状的数组reala(2,3),b(2,3),c(3,2)a(1,:)=(/1,2,3/);a(2,:)=(/4,5,6/)b=reshape((/1,2,3,4,5,6/),(/2,3/))doi=1,2print1,(a(i,j),j=1,3)enddodoi=1,2print1,(b(i,j),j=1,3)enddoc=reshape(a,(/3,2/))doi=1,3print1,(c(i,j),j=1,2)enddo1format(8(3x,f4.1))end输出结果为:1.02.03.04.05.06.01.03.05.02.04.06.01.05.04.03.02.06.0§6.1.5数组的操作可以把整个数组作为一个单独的对象进行算术、逻辑和关系运算。实际的运算仍然发生在元素级。因此,参与运算的数组必须有相同的形状。例如:B=sin(A),表示B数组的元素是A数组对应元素的正弦;B=A则表示B的元素与A的元素对应相等,相当于数学上矩阵与向量的相等定义。Fortran还提供了一些用于数组操作的内部函数,不过,实际用到的情况并不多见。§6.1.6数组片段数组片段是数组中部分元素的集合。相当于集合论中的子集。可以用下标三元组表示数组片段;下标三元组的格式为[下界]:[上界][:步长],可选项不出现时取缺省值。例:real,dimension(8,10)::A则A(2:6:2,2:8:3)是一个3x3的数组片段还可用下标向量表示数组片段:下标向量的元素是整数,代表数组片段中的元素在数组相应维数中的下标。§6.1.6数组片段例:real,dimension(8,10)::A,B(20)Integerc(4),d(3)C=(/2,4,7,8/);d=(/1,7,19/)B(d)=3.5!置B(1),B(7),B(19)为3.5B((/1,7,19/))=3.5!与上面相同A(5,c)=4.6!置A(5,2),A(5,4),A(5,7)与A(5,8)为4.6数组片段是FORTRAN90新增的概念,应该掌握。例如:Real,dimension(3,4)::aIntegerI(3),J(3)I=(/3,2,1/);J=(/2,3,4/)A=reshape((/1,2,3,4,5,6,7,8,9,10,11,12/),(/3,4/))PRINT*,A(I,J)END输出结果为:654987121110§6.1.7给数组元素赋初值格式:DATA变量表/初值表/[,变量表/初值表/例:DIMENSIONA(10),M(12),D(5,6)DATAR,A,K/-2,10*-3.5,-3/DATAR/-2/,K/-3/,(A(I),I=1,5)/5*-3.5/DATAU,V,W,X,D/4*-8.4,30*5.6/DATA语句的初值表中,连续相同的数字可以用个数*初值的形式表示,如果初值为负数,不得加括号。对单个数组元素赋值,与对变量赋值没有任何区别。对数组片段、数组的一部分元素或全体元素赋值,可采用隐含DO循环的方式。DATA语句中,初值表中的数值个数必须与变量表中变量个数相同。计数时,数组按其元素总数或隐含DO循环指定数量计。可以用DATA语句对同一个变量多次赋初值,但只有最后一次赋值有效。例:DIMENSIONR(6,6)DATAR,(R(I,I),I=1,6)/36*0.0,6*1.0/则数组R代表一个6阶单位矩阵。DATA语句是非执行语句,可以出现在说明语句之后、END语句之前。但是,DATA语句混在执行语句中间将降低程序的可读性,一般建议将DATA语句放在执行语句之前。§6.2动态数组在定义数组时,如果明确了它的大小与形状,这样的数组就是静态数组,它占用的内存大小是已知的,与定义它的程序单元具有相同的生存期。经常需要根据程序的输入数据或中间计算结果来确定数组的大小,这就可以用动态数组来实现。动态数组占用的内存大小是在程序执行期间按需分配的,满足需要又不浪费。动态数组占用的内存可以释放掉。§6.2动态数组动态数组的定义方式:类型说明,Dimension(RANK),Allocatable::数组名RANK规定了数组的维数,一个:代表一维,:之间用逗号隔开。不能指定各维的上下界。Real,Dimension(:),ALLocatable::AReal,Allocatable::B(:,:,:)定义了一维动态数组A与三维动态数组B。注意其区别。§6.2动态数组可以为动态数组分配内存:Allocate(数组名(维说明符))例real,allocatable::a(:,:)read*,m,nallocate(a(m,n))Read*,adoi=1,2print1,(a(i,j),j=1,3);enddo1format(8(3x,f4.1));deallocate(a);end§6.2动态数组可以释放动态数组的内存:DEAllocate(数组名)动态数组的元素个数可以是零。对动态数组必须先分配内存,然后才能使用和释放内存。虽然程序退出时会自动释放所有内存,将Allocate与DEAllocate配对使用仍然是建议养成的良好习惯。已经分配内存的动态数组不能再分配内存,要改变动态数组的大小时,必须先释放其内存,再重新为其分配内存。§6.2动态数组很明显:没有分配内存的动态数组不能释放其内存。作为虚参的数组不能是动态数组,因为它的大小是在过程调用时由相应的实参确定的,而不是由allocate()函数分配的。§6.3数组在函数和子程序中的应用§6.3.1显式形状数组显式形状数组的秩、大小、形状都是明确指定的。作为虚参时,其上下界可以由另外的虚参指定,该虚参值的变量不影响数组的上下界。例Subroutineex(a,b,C,M,N)Reala(50),b(2,3,4),C(M:N)M=M+NN=N-2§6.3数组在函数和子程序中的应用§6.3.2假定形状数组假定形状数组只能作为虚参,其秩是明确规定的,但其形状由实参确定。当下界指定时,上界会根据实参自动确定。例SubroutineAs(C)Real,Dimension(:,:)::C本过程只规定了数组C的秩为2;主调程序可以用任意的二维数组作为实参来调用它。§6.3数组在函数和子程序中的应用§6.3.3假定大小数组假定大小数组只能作为虚参,其最后一维的上界必须用星号*表示,表明其是可变的。例:SubroutineAsize(C)Real,Dimension(8,9,*)::C假定大小数组的形状可以与实参数组不同,它们按照在内存中的存储顺序一一对应。这就使假定大小数组的最后一维可能不完整,例如,调用上例过程时,实参大小不是72的倍数,必须防止使用未定义的数组元素。数组作为虚参(1)当虚参数组为数值型或逻辑型A:实参为同类型的数组名PROGRAMMAINSUBROUTINESUB(B)REALA(1:8)REALB(5)CALLSUB(A)A(1)A(2)A(3)A(4)A(5)A(6)A(7)A(8)B(1)B(2)B(3)B(4)B(5)PROGRAMMAINSUBROUTINESUB(B)REALC(3,3)REALB(5)CALLSUB(C)C(1,1)C(2,1)C(3,1)C(1,2)C(2,2)C(3,2)C(1,3)C(2,3)C(3,3)
本文标题:FORTRAN数组介绍大全
链接地址:https://www.777doc.com/doc-1342682 .html