1、 第十四章 公用区和存储关联 14.1 公用区一个 FORTRAN 90 程序,常常由多个程序单位(主程序、内部子程序、外部子程序、模块子程序等)组成,这些程序单位并不是一段孤立的程序代码,它们之间需要通过数据交换建立联系,相互影响,相互配合,共同完成一个特定任务。到目前,我们可通过主程序的全局变量或子程序的形实参结合方式实现程序单位之间的数据交换。对于大批量数据,这种数据交换方式的交换速度比较慢,一般只实用于所交换数据量比较少的情形。在求解某些实际问题时,程序单位之间需要进行大量的数据交换,这种情况下使用全程变量或形实参结合方式交换数据的效率较低。FORTRAN 语言提供公用区数据交换方式,
2、可高效完成大批量数据的交换任务。使用公用区可快速、方便、灵活地实现程序单位之间的数据交换。使用公用区交换数据的方法是:如果程序单位 A 要将数据传递给程序单位 B,必须先将数据传递给公用区,然后程序单位 B 在从公用区获得所需数据。公用区是程序单位之间交换数据的桥梁和中转站,通过公用区将程序单位紧密地联系在一起,如图 14-1 所示。FORTRAN 90 提供两种公用区:无名公用区和有名公用区。无名公用区指没有名称的公用区,一个程序只能有一个无名公用区。有名公用区指有名称的公用区,一个程序可有多个有名公用区。在程序的说明部分使用 COMMON 语句来设置无名或有名公用区。COMMON 语句是一
3、个非执行语句。各程序单位内的数据对象名称(变量名、数组名、数组说明符)是相互独立的,它们有各自的存储单元,即使同名也没有任何关系。如果我们在程序单位内使用 COMMON 语句,则使不同程序单位内的有关数据对象共同占用公用区中的存储单元,达到共享数据的目的。使用公用区求某班学生(人数不定)平均成绩的示例程序如下:公用区交换数据 交换数据程序单位 A 程序单位 B图 14-1 公用区与程序单位的关系PROGRAM mainINTEGER,PARAMETER : max=50 !定义对多学生人数常量 maxCOMMON score(max),n !在无名公用区设置成绩数组 score 和实际人数 n
4、!调用 input 子例行程序输入学生成绩数据至数组 scoreCALL input !无参子例行程序调用可取消括号!调用 average 函数统计平均成绩,使用公用区 score 数组数据和人数 n141 公用区38114.1.1 COMMON 语句COMMON 语句的一般格式是:COMMON /,av=average() !无参函数调用不能取消括号PRINT *,平均成绩为:,avCONTAINS!定义输入成绩数据的无参子例行程序 input,使用公用区数据SUBROUTINE input()!在无名公用区设置成绩数组 sc 和实际人数 m,依次与 score 和 n 对应COMMON s
5、c(max),m INTEGER i,xm=0READ*,xDO WHILE (x/=-1)m=m+1sc(m)=xREAD*,xENDDOEND SUBROUTINE!定义统计平均成绩的函数 average,使用公用区数据FUNCTION average()!在无名公用区设置成绩数组 sc 和实际人数 n,依次与 score 和 n 对应COMMON sc(max),nINTEGER i,sumsum=0DO i=1,nsum=sum+sc(i)ENDDOaverage=sum/nEND FUNCTIONEND说明:一个 COMMON 语句可设置一个或多个公用区,公用区用符号/命名,每个公用
6、区可设置一个或多个变量,变量之间用逗号“,”间隔,公用区变量声明只允许普通变量、数组、数组说明符。无名公用区可以仅写两个连续斜杠/,如果第一个公用区是无名公用区,则两个斜杠/可取消。第十四章 公用区和存储关联-382-下列 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、data2COMMON n,p/data1/a,x(10)/data2/r
7、,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 语句是合法的:INTEGER r,s,dat(30)COMMON m,n,r,num,dat,arr(50),matrixREAL num,matrix(5,4)无名公用区中设置了 4 个不同变
8、量和 3 个数组,其中:m 和 n 为普通整型变量,arr 为一维实型数组,它们遵循隐含规定;r 为普通整型变量,dat 为一维整型数组,其类型在前面INTEGER 语句中声明;num 为普通实型变量,matrix 为二维实型数组,其类型在后面 REAL 语句中声明。下列 COMMON 语句是合法的:COMMON /data1/a,b,c,d m1=10; m2=20; m3=30PRINT*,平均值为:,average()CONTAINSFUNCTION average()COMMON n,num(50)INTEGER sumDO i=1,nsum=sum+num(I)ENDDOaverag
9、e=sum/nEND FUNCTIONEND141 公用区385SUBROUTINE sub2()COMMON m,a,b,c,dEND SUBROUTINEEND使用有名公用区实现:PROGRAM mainCOMMON m /dat1/a,b /dat2/c,dCONTAINSSUBROUTINE sub1()COMMON m/dat1/a,bEND SUBROUTINESUBROUTINE sub2()COMMON m/dat2/c,dEND SUBROUTINEEND公用区结合方式和参数结合方式各有优缺点。当程序间交换的数据量不大时,则提倡使用参数结合方式交换数据,否则提倡使用公用区方式
10、。14.2 存储关联(等价)公用区的作用是使不同程序单位中的变量共享存储单元,而存储关联的作用是使同一程序单位中的变量共享存储单元。在程序中,使用等价语句 EQUIVALENCE 来实现存储关联。EQUIVALENCE 语句属于说明语句,也是一个非执行语句,必须出现在程序单位的说明部分。在一个程序中,所使用的变量并不总是在程序的整个执行期间有意义,有些变量只在程序的某个执行期间有意义。如果这些变量在完成了它们的使命后还占据存储单元,则会造成存储单元的极大浪费,有时这种浪费会很严重,甚至会影响程序的运行。我们将在程序不同执行期间(不相交)有意义的某些变量共享相同的存储单元,会有效解决存储单元浪费
11、问题,使用 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.0第十四章 公用区和存储关联-386-在这个程序中,使用了一个 EQUIVALENCE 语句使变量 sum 和 av 等价,它们共享相同的存储单元。程序中共使用了 4 个变量:i
12、、x、sum 和 av,其中:变量 i 有意义的程序执行区间为912 行,变量 x 有意义的程序执行区间为 1011 行,变量 sum 有意义的程序执行区间为 812行,变量 av 有意义的程序执行区间为 1314 行,从中发现,变量 sum 和 av 有意义的程序执行区间不相交,这种情况下它们共享存储单元不会发生任何问题,而且为程序节约了 4 个字节存储单元,如果等价的变量是数组,则节约的存储单元将比较可观。如果不使用 EQUIVALENCE语句使变量 sum 和 av 等价,则变量 sum 和 av 将分别占据 4 个字节存储单元,浪费 4 个字节存储单元。14.2.1 EQUIVALEN
13、CE 语句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 所示。tem(1) tem(2) tem(3) tem(4)mnsc(1)tem(5)sc(2)tem(6)
14、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)9 DO i=1,n10 READ *,x11 sum=sum+x12 ENDDO13 av=sum/n14 PRINT*,10 个测试数据的平均值为:, av15 END PROGRAM说明:EQUIVALENCE 语句后可跟多对括号,括号之间用逗号间隔。每对括号内声明一组等价变量,变量之间用逗号间隔。变量可以是普通变量、数组或数组元素。括号内至少有两个变量,不允许出现
15、子程序形式参数名。142 存储关联(等价)387图 14-4 变量存储分配及等价关系14.2.1 EQUIVALENCE 语句使用规则 EQUIVALENCE 语句中声明的等价变量一般要求类型相同,也可以不同,即一个整型变量可以和一个实型变量等价。例如,下面 EQUIVALENCE 语句是合法的:EQUIVALENCE (A,N) !变量 A 是实型,N 是整型 一个 EQUIVALENCE 语句可声明多组等价变量,如例14.6所示。 变量的等价关系满足传递原则,即:如果 a 和 b 等价,b 和 c 等价,则 a 和 c 等价。一个变量可出现在 EQUIVALENCE 语句中不同的括号内,但
16、不能出现矛盾的等价关系。下面 EQUIVALENCE 语句是合法的,数组 A 和 B 与普通变量 C 的等价关系如图 14-5 所示。REAL A(2,3),B(5),CEQUIVALENCE (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) !等价关系有矛盾 EQUIVALENCE 语句可使公用区中变量与非公用区变量等价,通过建立等价关系可扩充公用区大小
17、,只能向后扩充,不能向前扩充。下面 EQUIVALENCE 语句是合法的,数组 X 和 Y 与普通变量 T 的等价关系如图 14-6 所示。DIMENSION X(4),Y(7)COMMON X,TEQUIVALENCE (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 个实数,求两批数据对应数据的和与差,并输出,分别使用或不使用等价语句编写子例行程序实现之。分析存储
18、单元的使用情况。解: 下面给出不使用等价语句的子例行程序。SUBROUTINE sub1(X,Y)EQUIVALENCE 语句中声明的普通变量必须是经过显式声明或符合隐含规则的变量,声明的数组名或数组元素必须是经过显式声明的数组,否则将产生语法错误。第十四章 公用区和存储关联-388-INTEGER,PARAMETER :max=1000REAL,DIMENSUION(max) : X,Y,sum,difDO i=1,maxsum(i)=X(i)+Y(i)dif(i)=X(i)-y(i)ENDDOPRINT*,sumPRINT*, difEND SUBROUTINE下面给出不使用等价语句的子例
19、行程序。SUBROUTINE sub2(X,Y)INTEGER,PARAMETER :max=1000REAL,DIMENSUION(max) : X,Y,sum,difEQUIVALENCE (sum,dif)DO i=1,maxsum(i)=X(i)+Y(i)ENDDOPRINT*,sumDO i=1,maxdif(i)=X(i)-y(i)ENDDOPRINT*,difEND SUBROUTINE由于数组 sum 和 dif 等价,所以 sub2 子程序比 sub1 节约了 1000 个实数所占用的存储单元,即 4000 个字节。14.3 数据块子程序数据块子程序是一种特殊的子程序,它的主
20、要作用是集中对有关公用区变量进行初始化,集中为程序提供大量的原始数据。数据块子程序可以作为一个程序单元单独放在一个源程序文件中,可以单独编译,为程序的设计、编写、调试、修改提供方便。数据块子程序的一般格式是:BLOCK DATA END BLOCK DATA 说明:项可选,若该项缺省,则称数据块子程序为无名数据块子程序。数据块子程序名在程序中具有唯一性。项为数据块子程序的主体部分,只能出现必要的 USE 语句、类型说明语句、IMPLICIT 语句、PARAMETER 语句、派生类型定义语句、DIMENSION 语句、COMMON 语句、DATA 语句、EQUIVALENCE 语句、INTRIN
21、SIC 语句、POINTER 语句、TARGET 语句等,但不能出现任何可执行语句。类型说明语句不能包含 ALLOCATABLE、EXTERNAL、INTENT、OPTIONAL、PRIVATE、PUBLIC 属性。142 存储关联(等价)389例 14.8 分析下面程序,给出运行结果。解: !主程序单位PROGRAM mainIMPLICIT NONEINTEGER m,n,num(3)COMMON /blk1/m,n !声明一个有名公用区及两个公用区变量COMMON /num !声明一个无名公用区及一个公用区数组PRINT*,有名公用区 blk1 初始数据:,m,nPRINT*,无名公用区
22、初始数据 :,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,3s(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
Copyright © 2018-2021 Wenke99.com All rights reserved
工信部备案号:浙ICP备20026746号-2
公安局备案号:浙公网安备33038302330469号
本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。