FORTRAN90第六章数组.ppt

上传人:牧羊曲112 文档编号:6505863 上传时间:2023-11-07 格式:PPT 页数:46 大小:212.50KB
返回 下载 相关 举报
FORTRAN90第六章数组.ppt_第1页
第1页 / 共46页
FORTRAN90第六章数组.ppt_第2页
第2页 / 共46页
FORTRAN90第六章数组.ppt_第3页
第3页 / 共46页
FORTRAN90第六章数组.ppt_第4页
第4页 / 共46页
FORTRAN90第六章数组.ppt_第5页
第5页 / 共46页
点击查看更多>>
资源描述

《FORTRAN90第六章数组.ppt》由会员分享,可在线阅读,更多相关《FORTRAN90第六章数组.ppt(46页珍藏版)》请在三一办公上搜索。

1、6 数组,6.1 数组的定义与操作,6.2 动态数组,6.3 数组在函数和子程序中的应用,6.4 数组的应用举例,6.1 数组的定义与操作,数组:相同类型数据组成的有序的有限集合,数组必须先定义后使用。定义数组时,要对数组的名称、类型、数组的维数和元素的数量加以说明。,用类型说明结合DIMENSION属性进行定义:类型,dimension(维数说明,维数说明):数组名,数组名,6.1.1 数组的定义,维数说明:由下标界限说明组成,有几个下标界限说明就表示数组是几维的。多于一维的数组称多维数组,下标界限说明之间用逗号(,)分隔。,下标界限说明的写法:下标下限:下标上界下标界限为整数,上界必须大于

2、下界下标下界为1时可以连同后面的冒号一起省略;但是,上界是不可省略的。,定义数组时,下标界限必须为整型常量。,例:INTEGER,DIMENSION(-2:10):P定义一维整数组P,下标从-2到10,13个元素。,例:DIMENSION A(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个元素。,例:character c(100)*20定义一维字符数组C,有100个字符串,每

3、个可容纳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),特别提示:二维数组是按列存储的。,用数组名(

4、下标,下标)指定所要引用的数组元素。例: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 数组元素的引用,必须确保数组元素的下标的值不超过下标界限。如果下标越界,系统一般会对存储于数组之前(后)的存储单元进行操作(引用或者赋值),导致错误。,如果作为数组元素的下标的算术表达式中存在没有赋值的变量,系统一般自动将它按零处理,可能会导致计算结果不正

5、确,或者不稳定(时对时错)。这类错误很难发现,是许多程序存在bug的原因。,数组元素的下标表达式过于复杂时,最好先行算出,最好不要书写过于复杂的语句和表达式。,6.1.4 数组的输入与输出,数组必须先定义后使用,本节讨论中提到的数组假定已经定义如下:DIMENSION A(10),M(12),D(5,6),允许用数组名来I/O整个数组例:READ(*,*)A,M,D WRITE(*,*)A,D,多维数组I/O时,按其元素在内存中存储的顺序依次I/O各元素,遵守的原则是:最左边的下标变化最快。,特别提示:二维数组是按列存储的,在输入/输出时也按列进行。,在程序中可以输入/输出指定的元素,作为特例

6、,可用DO循环对数组全体元素或部分元素进行输入/输出。,Do I=1,5 do j=1,6 read*,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 数组的操作,数组赋值:可以给所有元素赋同一个值例:DIMENSION A(10),M(12),D(5,6)A=1.2;M=3;D=4.5,数

7、组构造器:(/取值列表/)取值列表:标量、隐DO表、向量。隐DO表和向量整体作为一个标量。标量之间用逗号。,数组构造器可给多维数组的某一维赋值:Real,Dimension(2,3):A,BA(1,:)=(/1,2,3/)!给第1行赋值A(2,:)=(/4,5,6/)!第2行,6.1.5 数组的操作,通过Reshape()函数可以把数组构造器的数据赋给某种形状的数组,real a(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/)do i=1,2print 1,(a(i,j),j

8、=1,3)enddo,do i=1,2print 1,(b(i,j),j=1,3)enddo c=reshape(a,(/3,2/)do i=1,3print 1,(c(i,j),j=1,2)enddo1 format(8(3x,f4.1)end,输出结果为:,1.0 2.0 3.04.0 5.0 6.01.0 3.0 5.02.0 4.0 6.01.0 5.04.0 3.02.0 6.0,6.1.5 数组的操作,可以把整个数组作为一个单独的对象进行算术、逻辑和关系运算。实际的运算仍然发生在元素级。因此,参与运算的数组必须有相同的形状。例如:B=sin(A),表示B数组的元素是A数组对应元素的

9、正弦;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

10、,B(20)Integer c(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):aInteger I(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,输出

11、结果为:6 5 4 9 8 7 12 11 10,6.1.7 给数组元素赋初值,格式:DATA 变量表/初值表/,变量表/初值表/例:DIMENSION A(10),M(12),D(5,6)DATA R,A,K/-2,10*-3.5,-3/DATA R/-2/,K/-3/,(A(I),I=1,5)/5*-3.5/DATA U,V,W,X,D/4*-8.4,30*5.6/,DATA语句的初值表中,连续相同的数字可以用个数*初值的形式表示,如果初值为负数,不得加括号。,对单个数组元素赋值,与对变量赋值没有任何区别。,对数组片段、数组的一部分元素或全体元素赋值,可采用隐含DO循环的方式。,DATA语

12、句中,初值表中的数值个数必须与变量表中变量个数相同。计数时,数组按其元素总数或隐含DO循环指定数量计。,可以用DATA语句对同一个变量多次赋初值,但只有最后一次赋值有效。,例:DIMENSION R(6,6)DATA R,(R(I,I),I=1,6)/36*0.0,6*1.0/则数组R代表一个6阶单位矩阵。,DATA语句是非执行语句,可以出现在说明语句之后、END语句之前。但是,DATA语句混在执行语句中间将降低程序的可读性,一般建议将DATA语句放在执行语句之前。,6.2 动态数组,在定义数组时,如果明确了它的大小与形状,这样的数组就是静态数组,它占用的内存大小是已知的,与定义它的程序单元具

13、有相同的生存期。,经常需要根据程序的输入数据或中间计算结果来确定数组的大小,这就可以用动态数组来实现。动态数组占用的内存大小是在程序执行期间按需分配的,满足需要又不浪费。,动态数组占用的内存可以释放掉。,6.2 动态数组,动态数组的定义方式:类型说明,Dimension(RANK),Allocatable:数组名RANK规定了数组的维数,一个:代表一维,:之间用逗号隔开。不能指定各维的上下界。,Real,Dimension(:),ALLocatable:A Real,Allocatable:B(:,:,:)定义了一维动态数组A与三维动态数组B。注意其区别。,6.2 动态数组,可以为动态数组分配

14、内存:Allocate(数组名(维说明符),例real,allocatable:a(:,:)read*,m,nallocate(a(m,n)Read*,ado i=1,2print 1,(a(i,j),j=1,3);enddo1 format(8(3x,f4.1);deallocate(a);end,6.2 动态数组,可以释放动态数组的内存:DEAllocate(数组名),动态数组的元素个数可以是零。对动态数组必须先分配内存,然后才能使用和释放内存。虽然程序退出时会自动释放所有内存,将Allocate与DEAllocate配对使用仍然是建议养成的良好习惯。已经分配内存的动态数组不能再分配内存,

15、要改变动态数组的大小时,必须先释放其内存,再重新为其分配内存。,6.2 动态数组,很明显:没有分配内存的动态数组不能释放其内存。作为虚参的数组不能是动态数组,因为它的大小是在过程调用时由相应的实参确定的,而不是由allocate()函数分配的。,6.3 数组在函数和子程序中的应用,6.3.1 显式形状数组显式形状数组的秩、大小、形状都是明确指定的。作为虚参时,其上下界可以由另外的虚参指定,该虚参值的变量不影响数组的上下界。,例Subroutine ex(a,b,C,M,N)Real a(50),b(2,3,4),C(M:N)M=M+NN=N-2,6.3 数组在函数和子程序中的应用,6.3.2

16、假定形状数组假定形状数组只能作为虚参,其秩是明确规定的,但其形状由实参确定。当下界指定时,上界会根据实参自动确定。,例Subroutine As(C)Real,Dimension(:,:):C本过程只规定了数组C的秩为2;主调程序可以用任意的二维数组作为实参来调用它。,6.3 数组在函数和子程序中的应用,6.3.3 假定大小数组假定大小数组只能作为虚参,其最后一维的上界必须用星号*表示,表明其是可变的。,例:Subroutine Asize(C)Real,Dimension(8,9,*):C,假定大小数组的形状可以与实参数组不同,它们按照在内存中的存储顺序一一对应。这就使假定大小数组的最后一维

17、可能不完整,例如,调用上例过程时,实参大小不是72的倍数,必须防止使用未定义的数组元素。,数组作为虚参,(1)当虚参数组为数值型或逻辑型A:实参为同类型的数组名PROGRAM MAIN SUBROUTINE SUB(B)REAL A(1:8)REAL B(5)CALL SUB(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),PROGRAM MAIN SUBROUTINE SUB(B)REAL C(3,3)REAL B(5)CALL SUB(C)C(1,1)C(2,1)C(3,1)C(1,2)C(2,2)C(3,2)C(1,3)C(2

18、,3)C(3,3)B(1)B(2)B(3)B(4)B(5)注意:虚参数组的元素个数必须小于等于实参数组的元素个数.B:实参为同类型的数组元素CALL SUB(A(3)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),CALL SUB(C(1,2)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)B(1)B(2)B(3)B(4)B(5)注意:虚参数组不能越出实参数组的范围.如CALL SUB(C(3,2)是错误的(2)当虚参数组为字符型,实参为同类型的数组名或数组元素,虚参与实参是按

19、字符位置一一对应.PROGRAM MAIN SUBROUTINE SUB(B)CHARACTER*4 A(5)CHARACTER*3 B(4)CALL SUB(A),parameter(n=20)integer a(n),Xdata a/52,98,-45,0,8,10,-23,6,25,12,&-89,8,4,15,2,-5,81,60,32,75/write(*,100)awrite(*,*)Enter a number for searchread(*,*)Xdo k=1,n,例1(顺序查找):在一组数据中查找数据X,6.4 数组的应用举例,if(x=A(k)then write(*,1

20、20)K,X;STOP endif ENDDO write(*,*)X,Could not be found!100 format(1x,Ordinary:/(1x,10i6)120 format(1x,The,I3,th number is,I3)end,顺序查找要对所有数据进行比较,因此也叫遍历式查找。,如果数据X多次出现在数组中,本程序只能查找到第一次出现的位置。,parameter(N=10)INTEGER A(N)Data a/18,10,6,25,12,8,4,15,2,-5/WRITE(*,100)ADO I=1,N-1DO J=N,I+1,-1 IF(A(J).LT.A(J-1

21、)THEN M=A(J);A(J)=A(J-1);A(J-1)=M ENDIFENDOENDO,例2(冒泡排序):把一组数据从小到大排列,WRITE(*,120)A100 FORMAT(1X,Ordinary:/(1X,10I6)120 FORMAT(1X,Sorted:/(1X,10I6)END,例3(选择排序):把一组数据从小到大排列,parameter(n=10)integer a(n),pread(*,*)a;write(*,100)ado i=1,n-1 p=I do j=i+1,n;if(a(j)a(p)p=j;Enddo if(p/=i)then j=a(p);a(p)=a(i)

22、;a(i)=j endifEnddo,write(*,120)a100 format(1x,Ordinary:/(1x,10i6)120 format(1x,Sorted:/(1x,10i6)end,数理统计:输入20个学生的学号、姓名和一门功课的成绩,打印出最高分、最低分、全班平均分和高出平均分的学生学号、姓名与成绩。Parameter(N=20)DIMENSION S(N)character*8 num(n),name(n)write(*,*)Enter No and Score and NameREAD(*,100)(num(I),s(I),name(I),I=1,n)Sum=s(1);

23、Smin=S(1);Smax=S(1)DO I=2,N if(smin s(I)smin=s(I)if(smax S(I)smax=s(I),Sum=Sum+A(I)ENDDOAV=Sum/N;write(*,110)Smax,Smin,AVwrite(*,150)DO I=1,N if(S(I)AV)rite(*,120)num(I),name(I),s(I)ENDDO100 Format(A,F8.1,A)110Format(1x,H=,F3.0,L=,F3.0,A=,F3.0)120Format(1X,2A10,F8.1)150 Format(1x,No,8x,Name,8x,Score

24、)END,数组程序举例例1:输入20名学生的成绩,统计各分数段人数。分数段为:09,1019,2029,.9099,100 c(0),c(1),c(2),c(9),c(10)输入一个成绩G,需要进行下列判断:DO I=0,10IF(I*10.LE.G.AND.G.LT.(I+1)*10)C(I)=C(I)+1END成绩G和数组C的下标K有下列关系K=G/10程序为:,Real,dimension(1:20):GINTEGER C(0:10),KC=0DO I=1,20READ*,G(I)K=G(I)/10C(K)=C(K)+1END DOPRINT*,(C(I),I=0,10)END,例2:输

25、入20名学生的学号和一门课的成绩,统计不及格的人数,并把不及格的学生学号和成绩打印出来。数组NUM存放学号,数组G存放成绩CHARACTER*10 NUM(20)REAL G(20)DO I=1,20READ*,NUM(I),G(I)END DON=0DO I=1,20IF(G(I).LT.60)THENN=N+1;PRINT*,NUM(I),G(I)END DOEND,例3:顺序查找A:5 3 7 11 20 9 18 11X=11下列程序段用来查找数组A中是否包含XP=1DO WHILE(A(P).NE.X.AND.P.LT.N)P=P+1END DO在二种情况下退出循环:(1)A(P)=

26、X;此时在A中找到X(2)P=N;即X与A(1),A(2),.A(N-1)均不相同,还要判断与A(N)是否相等,由于此时P=N,即要判断X与A(P)是否相等。程序为:,Parameter(n=20)Integer,dimension(1:n):aInteger x,pRead*,(a(I),I=1,n)Read*,xP=1Do)p=p+1End doIf(x.eq.a(p)then print*,在数组A中找到,X,位置为,PELSEprint*,在数组A没有找到,XEND IFEND,例4:在一有序数列中,插入一数,使插PARAMETER(N=30)入后的数列仍然有序.INTEGER A(N

27、)A 3,5,11,22,28,56,76,88READ*,N1X=45READ*,(A(I),I=1,N1)第一步,先找插入的位置PREAD*,XP=1 P=1DO WHILE(X.GT.A(P).AND.P.LE.N1)DO WHILE(X.GT.A(P).AND.P.LE.N1)P=P+1P=P+1END DOEND DO第二步,完成插入DO I=N1,P,-1 DO I=N1,P,-1 A(I+1)=A(I)A(I+1)=A(I)END DO;A(P)=XEND DON1=N1+1A(P)=XN1=N1+1PRINT*,(A(I),I=1,N1)END,例5:求二维数组的鞍点,即该点在

28、行上最小,列上最大。求第I行最小元素的程序段为:Q=1DO J=2,NIF(A(I,Q).GT.A(I,J)Q=JEND DO求第Q列最大元素的程序段为:P=1DO K=2,MIF(A(P,Q).LT.A(K,Q)P=KEND DO如果P=I,说明元素A(P,Q)是鞍点,Subroutine sub(a,m,n,l)Logical:l=.FALSE.Real a(m,n)Integer p,qDo I=1,mQ=1DO J=2,NIF(A(I,Q).GT.A(I,J)Q=JEND DOP=1DO K=2,MIF(A(P,Q).LT.A(K,Q)P=KEND DOIf(p.eq.I)thenpr

29、int*,p,q,是鞍点L=.true.End doEnd Subroutine sub,例如:输入一个45的矩阵,求其鞍点Parameter(m=4,n=5)Real,dimension(m:n):aLogical:l=.false.Read*,(a(I,j),j=1,5),I=1,4)!按行输入Call sub(a,m,n,l)If(.not.l)print*,没有鞍点end,例6:打印杨辉三角形的前十行111 2 13 3 11 4 6 4 1.,第I行需求的元素的值为(I3):a(I,2),a(I,3),.a(I,I-1)且:a(I,j)=a(I-1,j)+a(I-1,j-1)输出时,第I行需输出I个元素:a(I,1),a(I,2),.a(I,I),可用下列语句实现Write(*,*)(a(I,j),j=1,I),程序为:Integer,dimension(10,10):aa=0Do I=1,10a(I,I)=1;a(I,1)=1End doDo I=3,10 do j=2,I-1 a(I,j)=a(I-1,j)+a(I-1,j-1)end doEnd doDo I=1,10 Write(*,*)(a(I,j),j=1,I)End doend,

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

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号