fortran90程序设计chapter14.doc_第1页
fortran90程序设计chapter14.doc_第2页
fortran90程序设计chapter14.doc_第3页
fortran90程序设计chapter14.doc_第4页
fortran90程序设计chapter14.doc_第5页
已阅读5页,还剩8页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

141 公用区 第十四章 公用区和存储关联 14.1 公用区一个FORTRAN 90程序,常常由多个程序单位(主程序、内部子程序、外部子程序、模块子程序等)组成,这些程序单位并不是一段孤立的程序代码,它们之间需要通过数据交换建立联系,相互影响,相互配合,共同完成一个特定任务。到目前,我们可通过主程序的全局变量或子程序的形实参结合方式实现程序单位之间的数据交换。对于大批量数据,这种数据交换方式的交换速度比较慢,一般只实用于所交换数据量比较少的情形。在求解某些实际问题时,程序单位之间需要进行大量的数据交换,这种情况下使用全程变量或形实参结合方式交换数据的效率较低。FORTRAN语言提供公用区数据交换方式,可高效完成大批量数据的交换任务。使用公用区可快速、方便、灵活地实现程序单位之间的数据交换。使用公用区交换数据的方法是:如果程序单位A要将数据传递给程序单位B,必须先将数据传递给公用区,然后程序单位B在从公用区获得所需数据。公用区是程序单位之间交换数据的桥梁和中转站,通过公用区将程序单位紧密地联系在一起,如图14-1所示。公用区交换数据交换数据程序单位A程序单位B图14-1 公用区与程序单位的关系FORTRAN 90提供两种公用区:无名公用区和有名公用区。无名公用区指没有名称的公用区,一个程序只能有一个无名公用区。有名公用区指有名称的公用区,一个程序可有多个有名公用区。在程序的说明部分使用COMMON语句来设置无名或有名公用区。COMMON语句是一个非执行语句。各程序单位内的数据对象名称(变量名、数组名、数组说明符)是相互独立的,它们有各自的存储单元,即使同名也没有任何关系。如果我们在程序单位内使用COMMON语句,则使不同程序单位内的有关数据对象共同占用公用区中的存储单元,达到共享数据的目的。使用公用区求某班学生(人数不定)平均成绩的示例程序如下:PROGRAM main INTEGER,PARAMETER : max=50 !定义对多学生人数常量max COMMON score(max),n !在无名公用区设置成绩数组score和实际人数n !调用input子例行程序输入学生成绩数据至数组score CALL input !无参子例行程序调用可取消括号 !调用average函数统计平均成绩,使用公用区score数组数据和人数n av=average() !无参函数调用不能取消括号 PRINT *,平均成绩为:,avCONTAINS !定义输入成绩数据的无参子例行程序input,使用公用区数据 SUBROUTINE input() !在无名公用区设置成绩数组sc和实际人数m,依次与score和n对应 COMMON sc(max),m INTEGER i,x m=0 READ*,x DO WHILE (x/=-1) m=m+1 sc(m)=x READ*,x ENDDO END SUBROUTINE !定义统计平均成绩的函数average,使用公用区数据 FUNCTION average() !在无名公用区设置成绩数组sc和实际人数n,依次与score和n对应 COMMON sc(max),n INTEGER i,sum sum=0 DO i=1,n sum=sum+sc(i) ENDDO average=sum/n END FUNCTIONEND 14.1.1 COMMON语句COMMON语句的一般格式是:COMMON /,说明: 一个COMMON语句可设置一个或多个公用区,公用区用符号/命名,每个公用区可设置一个或多个变量,变量之间用逗号“,”间隔,公用区变量声明只允许普通变量、数组、数组说明符。无名公用区可以仅写两个连续斜杠/,如果第一个公用区是无名公用区,则两个斜杠/可取消。 下列COMMON语句是合法的: COMMON m,n,x,y,arr(30) !设置一个无名公用区 COMMON /m,n, x,y,arr(30) !设置一个无名公用区 COMMON /data/a,b(10),n !设置1个有名公用区data !设置1个无名公用区和2个有名公用区data1、data2 COMMON n,p/data1/a,x(10)/data2/r,s !第一个公用区为无名公用区 COMMON /num,p/data1/a,x(10)/data2/r,s !第一个公用区为无名公用区 COMMON /data1/a,x(10)/num,p/data2/r,s !第二个公用区为无名公用区 COMMON /data1/a,x(10)/data2/r,s/num,p !第三个公用区为无名公用区 !公用区变量类型遵循I-N隐含规则 一般情况下,COMMON语句中变量的类型遵循I-N隐含规则,除非使用类型声明语句对其进行了显式声明。如果数组被显式声明,则在COMMON语句中只能给出数组名。如果COMMON语句中给出数组说明符,则类型声明语句只能给出数组名。类型声明语句和COMMON语句不能给出相同的数组说明符。 下列类型声明和COMMON语句是合法的: INTEGER r,s,dat(30) COMMON m,n,r,num,dat,arr(50),matrix REAL num,matrix(5,4)无名公用区中设置了4个不同变量和3个数组,其中:m和n为普通整型变量,arr为一维实型数组,它们遵循隐含规定;r为普通整型变量,dat为一维整型数组,其类型在前面INTEGER语句中声明;num为普通实型变量,matrix为二维实型数组,其类型在后面REAL语句中声明。 COMMON语句一行写不下时,可续行。如果是有名公用区,则可分多个COMMON语句书写。 下列COMMON语句是合法的: COMMON /data1/a,b,c,d & &/data2/x(10),y(20)或 COMMON /data1/a,b,c,d COMMON /data2/x(10),y(20)14.1.2 公用区特性和使用规则l 每一公用区有确定的大小。编译系统根据每一公用区设置的变量和数组分配所需存储单元,确定公用区大小,所以公用区设置的变量和数组不允许是子程序的形式参数(虚参),不允许设置动态数组。例如,下列COMMON语句设置的无名公用区占据214个字节,其中:3个整型变量占7个字节,一个单精度实型变量占4个字节,一个整型数组占200个字节。 INTEGER(1) m !m的KIND值为1,分配1个字节存储单元 INTEGER(2) n !n的KIND值为2,分配2个字节存储单元 INTEGER r !r的KIND值为4,分配4个字节存储单元 COMMON m,n,r,a,num(50) !a为实型变量,KIND值为4,分配4个字节存储单元 !num为一维整型变量,有50个数组元素,共分配200个字节存储单元l 一个公用区的所有变量在该公用区存储区域中排列次序与COMMON语句中声明的次序一致。例14.1 设m,n为整型变量,a,b为单精度实型变量,c为复型变量,x为一维实型数组。分析下列COMMON语句,计算公用区存储区域大小,并指出公用区变量的排列次序。 COMMON m,a,n,b,c,x(5)解:COMMON语句设置了一个无名公用区。公用区大小为44字节,其中:每个整型变量占4个字节,每个单精度实型变量占4个字节,每个复型变量占8个字节,一个数组占20个字节。公用区中变量的排列次序如图14-2所示。manbcx(1)x(2)x(3)x(4)x(5)4444844444图14-2 变量排列次序及存储分配l 不同程序单位中设置同一公用区,其声明的变量位置要保证对应,否则数据交换不能正确进行。同一公用区中对应变量的名称可以不同,但类型一般应相同。例14.2 给出主程序和子程序中的COMMON语句,指出公用区变量和对应关系。 主程序:COMMON /data/m1,m2,a,x(3) 子程序:COMMON /data/n1,n2,y(2,2)解:公用区变量和对应关系如图14-3所示。公用区data主程序m1m2ax(1)x(2)x(3)子程序n1n2y(1,1)y(1,2)y(2,1)y(2,2)图14-3 公用区内容和对应关系l 在公用区中可设置一些虚变量,以便与特定变量建立联系。如果只需要公用区中某个或某些变量,则通过设置虚变量来实现。例14.3 给出主程序中的COMMON语句。子程序中需要公用区中m2和x数组中的数据,给出子程序中正确的COMMON语句。 主程序:COMMON /data/m1,m2,a,x(4) 解:子程序中COMMON语句为: 子程序:COMMON /data/nn,n2,aa,y(2,2) 子程序中变量nn和aa为虚变量。l 在保证类型一致的情况下,同类型普通变量可以与数组对应。l 在不同程序单位内使用同一有名公用区,其大小必须相同,使用无名公用区,其大小可以不同。例14.4 执行下面程序,给出输出结果。PROGRAM main COMMON m,m1,m2,m3 m=3; m1=10; m2=20; m3=30 PRINT*,平均值为:,average()CONTAINS FUNCTION average() COMMON n,num(50) INTEGER sum DO i=1,n sum=sum+num(I) ENDDO average=sum/n END FUNCTION END 解:程序运行结果为: 平均值为: 20.0000014.1.3 有名公用区的作用公用区使用比较灵活、方便、清晰。对于一批数据,不同的程序单位需要存取其中不同的部分数据,如果使用无名公用区,则在这些程序单位的COMMON语句中都要设置存储这批数据的变量,如果使用有名公用区,则在这些程序单位的COMMON语句中有选择地设置所需要的变量。例14.5 假设有5个数据:m、a、b、c、d。主程序main需要全部5个数据,子程序sub1需要其中3个数据:m、a、b,子程序sub2需要其中3个数据:m、c、d。分别使用无名公用区和有名公用区实现之。解:使用无名公用区实现: PROGRAM main COMMON m,a,b,c,d CONTAINS SUBROUTINE sub1() COMMON m,a,b,c,d END SUBROUTINE SUBROUTINE sub2() COMMON m,a,b,c,d391142 存储关联(等价) END SUBROUTINE END使用有名公用区实现: PROGRAM main COMMON m /dat1/a,b /dat2/c,d CONTAINS SUBROUTINE sub1() COMMON m/dat1/a,b END SUBROUTINE SUBROUTINE sub2() COMMON m/dat2/c,d END SUBROUTINE END公用区结合方式和参数结合方式各有优缺点。当程序间交换的数据量不大时,则提倡使用参数结合方式交换数据,否则提倡使用公用区方式。14.2 存储关联(等价)公用区的作用是使不同程序单位中的变量共享存储单元,而存储关联的作用是使同一程序单位中的变量共享存储单元。在程序中,使用等价语句EQUIVALENCE来实现存储关联。EQUIVALENCE语句属于说明语句,也是一个非执行语句,必须出现在程序单位的说明部分。在一个程序中,所使用的变量并不总是在程序的整个执行期间有意义,有些变量只在程序的某个执行期间有意义。如果这些变量在完成了它们的使命后还占据存储单元,则会造成存储单元的极大浪费,有时这种浪费会很严重,甚至会影响程序的运行。我们将在程序不同执行期间(不相交)有意义的某些变量共享相同的存储单元,会有效解决存储单元浪费问题,使用EQUIVALENCE语句可达到这一目的。下面给出使用EQUIVALENCE语句实现求10个测试数据平均值的示例程序。1 PROGRAM average22 IMPLICIT NONE3 INTEGER,PARAMETER : n=104 EQUIVALENCE(sum,av)5 REAL x,sum,av6 INTEGER i7 PRINT*,输入10个测试数据(一行一个):8 sum=0.09 DO i=1,n10 READ *,x11 sum=sum+x12 ENDDO13 av=sum/n14 PRINT*,10个测试数据的平均值为:, av15 END PROGRAM 在这个程序中,使用了一个EQUIVALENCE语句使变量sum和av等价,它们共享相同的存储单元。程序中共使用了4个变量:i、x、sum和av,其中:变量i有意义的程序执行区间为912行,变量x有意义的程序执行区间为1011行,变量sum有意义的程序执行区间为812行,变量av有意义的程序执行区间为1314行,从中发现,变量sum和av有意义的程序执行区间不相交,这种情况下它们共享存储单元不会发生任何问题,而且为程序节约了4个字节存储单元,如果等价的变量是数组,则节约的存储单元将比较可观。如果不使用EQUIVALENCE语句使变量sum和av等价,则变量sum和av将分别占据4个字节存储单元,浪费4个字节存储单元。14.2.1 EQUIVALENCE语句EQUIVALENCE语句的一般格式是:EQUIVALENCE (),() 例14.6 根据下面类型说明和等价语句,分析并指出变量之间的关联关系。 INTEGER m,n,sc(5),tem(9),num(4),mat(2,3) EQUIVALENCE (m,n,sc,tem(5),(num,mat(1,2)解:第1个括号声明了普通变量m和n,以及数元素sc(1)和tem(5)等价,第2个括号声明了数组元素num(1)和mat(2,1)等价。如图14-4所示。说明: EQUIVALENCE语句后可跟多对括号,括号之间用逗号间隔。每对括号内声明一组等价变量,变量之间用逗号间隔。变量可以是普通变量、数组或数组元素。括号内至少有两个变量,不允许出现子程序形式参数名。tem(1)tem(2)tem(3)tem(4)mnsc(1)tem(5)sc(2)tem(6)sc(3)tem(7)sc(4)tem(8)sc(5)tem(9)num(1)num(2)num(3)num(4)mat(1,1)mat(1,2)mat(1,3)mat(2,1)mat(2,2)mat(2,3)图14-4 变量存储分配及等价关系 EQUIVALENCE语句中声明的普通变量必须是经过显式声明或符合隐含规则的变量,声明的数组名或数组元素必须是经过显式声明的数组,否则将产生语法错误。14.2.1 EQUIVALENCE语句使用规则l EQUIVALENCE语句中声明的等价变量一般要求类型相同,也可以不同,即一个整型变量可以和一个实型变量等价。例如,下面EQUIVALENCE语句是合法的: EQUIVALENCE (A,N) !变量A是实型,N是整型l 一个EQUIVALENCE语句可声明多组等价变量,如例14.6所示。l 变量的等价关系满足传递原则,即:如果a和b等价,b和c等价,则a和c等价。一个变量可出现在EQUIVALENCE语句中不同的括号内,但不能出现矛盾的等价关系。 下面EQUIVALENCE语句是合法的,数组A和B与普通变量C的等价关系如图14-5所示。 REAL A(2,3),B(5),C EQUIVALENCE (A(1,2),C),(B(3),C)B(1)A(1,1)B(2)A(1,2)CB(3)A(1,3)B(4)A(2,1)B(5)A(2,2)A(2,3)图14-5 变量存储分配及等价关系下面EQUIVALENCE语句是不合法的: EQUIVALENCE (C,B(2),(C,(B5) !等价关系有矛盾l EQUIVALENCE语句可使公用区中变量与非公用区变量等价,通过建立等价关系可扩充公用区大小,只能向后扩充,不能向前扩充。 下面EQUIVALENCE语句是合法的,数组X和Y与普通变量T的等价关系如图14-6所示。 DIMENSION X(4),Y(7) COMMON X,T EQUIVALENCE (X(3),Y(2)X(1)X(2)Y(1)X(3)Y(2)X(4)Y(3)TY(4)Y(5)Y(6)Y(7)图14-6 变量存储分配及等价关系 使用EQUIVALENCE语句后,无名公用区向后增加了3个实数存储单元。例14.7 已知两批数据,每批有1000个实数,求两批数据对应数据的和与差,并输出,分别使用或不使用等价语句编写子例行程序实现之。分析存储单元的使用情况。解: 下面给出不使用等价语句的子例行程序。 SUBROUTINE sub1(X,Y) INTEGER,PARAMETER :max=1000 REAL,DIMENSUION(max) : X,Y,sum,dif DO i=1,max sum(i)=X(i)+Y(i) dif(i)=X(i)-y(i) ENDDO PRINT*,sum PRINT*, dif END SUBROUTINE下面给出不使用等价语句的子例行程序。 SUBROUTINE sub2(X,Y) INTEGER,PARAMETER :max=1000 REAL,DIMENSUION(max) : X,Y,sum,dif EQUIVALENCE (sum,dif) DO i=1,max sum(i)=X(i)+Y(i) ENDDO PRINT*,sum DO i=1,max dif(i)=X(i)-y(i) ENDDO PRINT*,dif END SUBROUTINE由于数组sum和dif等价,所以sub2子程序比sub1节约了1000个实数所占用的存储单元,即4000个字节。14.3 数据块子程序数据块子程序是一种特殊的子程序,它的主要作用是集中对有关公用区变量进行初始化,集中为程序提供大量的原始数据。数据块子程序可以作为一个程序单元单独放在一个源程序文件中,可以单独编译,为程序的设计、编写、调试、修改提供方便。数据块子程序的一般格式是:BLOCK DATA END BLOCK DATA 说明:项可选,若该项缺省,则称数据块子程序为无名数据块子程序。数据块子程序名在程序中具有唯一性。项为数据块子程序的主体部分,只能出现必要的USE语句、类型说明语句、IMPLICIT语句、PARAMETER语句、派生类型定义语句、DIMENSION语句、COMMON语句、DATA语句、EQUIVALENCE语句、INTRINSIC语句、POINTER语句、TARGET语句等,但不能出现任何可执行语句。类型说明语句不能包含ALLOCATABLE、EXTERNAL、INTENT、OPTIONAL、PRIVATE、PUBLIC属性。143 数据块子程序例14.8 分析下面程序,给出运行结果。解: !主程序单位PROGRAM mainIMPLICIT NONEINTEGER m,n,num(3)COMMON /blk1/m,n !声明一个有名公用区及两个公用区变量COMMON /num !声明一个无名公用区及一个公用区数组PRINT*,有名公用区blk1初始数据:,m,nPRINT*,无名公用区初始数据 :,numcall procPRINT*,有名公用区blk1最新数据:,m,nPRINT*,无名公用区最新数据 :,numEND PROGRAM mainprint*,main,m,n,m1,n1END PROGRAM!外部子程序单位SUBROUTINE procIMPLICIT NONEINTEGER x,y,s(3),ICOMMON /blk1/x,y !声明一个有名公用区及两个公用区变量COMMON /s !声明一个无名公用区及一个公用区数组x=x+10;y=y+10DO I=1,3 s(I)=s(I)+10ENDDOEND!数据块子程序单位BLOCK DATA blockIMPLICIT NONEINTEGER a,b,r(3)COMMON /blk1/a,b !声明一个有名公用区及两个公用区变量COMMON /r !声明一个无名公用区及一个公用区数组DATA a,b/10,20/DATA r/11,22,33/END数据块子程序中对有名公用区中变量和数组进行了初始化,在公用区中生成了原始数据。主程序单位首先输出了公用区中原始数据,然后调用子例行程序,子例行程序修改公用区中数据,每个变量增加10,最后主程序输出公用区最新数据。运行程序,输出结果为: 有名公用区blk1初始数据: 10 20 无名公用区初始数据 : 11 22 33 有名公用区blk1最新数据: 20 30 无名公用区最新数据 : 21 32 43使用数据块子程序注意事项:l 在一个程序中,可有多个有名数据块子程序,但只能有一个无名数据块子程序。l 数据块子程序中必须用COMMON语句声明公用区,通常需要使用DATA语句对公用区变量赋初值,特殊情况可以不赋初值。l 在一个程序的主程序单位、子程序单位、数据块子程序单位中只能有一个程序单位对公用区变量赋初值。l 公用区中变量必须通过隐含规则或显式类型声明语句声明类型。l 在数据块子程序中,公用区的指针变量不能赋初值。例14.9 使用数据块子程序保存多项式系数A0,A1,A2,An和阶数n。从键盘输入未知数X,从数据块子程序公用区获得多项式系数和阶数,计算多项式的值并输出。 1.2+2.5X1-3.1X2+4.5X3-2.3X4+7.5X5-5.4X6+0.5X7!主程序单位PROGRAM polynomialUSE maximumINTEGER n REAL A(0:max),XCOMMON /blk1/n,A !声明一个有名公用区及一个变量、一个数组PRINT*,输入多项式未知数X的值:READ*,XPRINT*,多项式的值为:,p(X)END PROGRAM polynomial!外部函数FUNCTION p(X)USE maximumINTEGER n REAL A(0:max),X,p,p1COMMON /blk1/n,A !声明一个有名公用区及一个变量、一个数组p1=A(n)DO I=n-1,0,-1 p1=p1*X+A(I)ENDDOp=p1END FUNCTION pEND习题十四!数据块子程序单位BLOCK DATA coefficientUSE maximumINTEGER n REAL A(0:max)COMMON /blk1/n,A !声明一个有名公用区及一个变量、一个数组DATA n,A/7,1.2,2.5,-3.1,4.5,-2.3,7.5,-5.4,0.5/END运行程序,输入X值为1.5,输出结果为: 多项式的值为: 5.505468!模块单元MODULE maximumIMPLICIT NONEINTEGER,PARAMETER : max=20END MODULE maxmimum习题十四1 何谓公用区?为什么要使用公用区?它与参数结合方式交换数据有何不同之处?2 公用区分哪几种类型?简述每类公用区的主要特点。3 公用区大

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论