FORTRAN中的数组 (2).ppt
《FORTRAN中的数组 (2).ppt》由会员分享,可在线阅读,更多相关《FORTRAN中的数组 (2).ppt(56页珍藏版)》请在三一办公上搜索。
1、第9章 Fortran中的数组,数组是Fortran语言中功能最为强大、运用最为灵活的一种数据结构。数组(ARRAY)在科学和工程计算中通常用来表示矩阵和向量。同一般的变量声明相比,数组能够同时保存多个数据。它是一种使用大规模数据的方法。配合Fortran语言中的数组操作,可用于对大量不同的数据进行处理。在存储结构上,数组占用一片连续的存储单元。程序中通过数组索引来对数组元素、片断进行操作。,9.1 数组的定义,要在程序中使用数组,需要首先在变量声明中进行数组定义。数组定义规定了数组的维数和大小,以及数组所能保存的数据类型。在程序中,通过数组引用来对数组、数组元素或者数组片断进行操作。数组是类
2、型相同、种别一致的一组变量的有序集合。它可以是整型、实型、双精度型、复型、逻辑型、字符型以及自定义类型等中的任意一种。组成数组的每一个变量被称为数组元素,并由唯一的下标来进行标识。数组定义说明了数组所能保存的数据类型、数组的维数、维的范围和数组的大小。本节主要介绍Fortran中数组定义的几种方式。,9.1.1 定义形式一,第一种数组定义形式的语法格式如下所示。类型说明:数组名(下标下界:下标上界,),该定义形式通过类型说明来显式声明数组的数据类型,并通过下标下界和下标上界来规定数组中某一维的范围。下标下界和下标上界共同组成了维说明符。当维说明符省略下标下界时,默认所在维的下标从1开始。如下代
3、码都是合法的数组定义。REAL:A(1:2,2:4)INTEGER B(10),9.1.2 定义形式二,第二种数组定义形式的语法格式如下所示。DIMENSION:数组名(下标下界:下标上界,),类型说明:数组名,该定义形式通过DIMENSION语句来进行数组的定义,通过下标下界和下标上界来规定数组中某一维的范围。在第二行通过类型说明来显式声明数组的数据类型。当省略类型说明时,采用默认的“I-N”规则来对数组的数据类型进行定义。如下代码合法的对数组进行了定义。DIMENSION:A(10),B(2:11)INTEGER:A,9.1.3 定义形式三,第三种数组定义形式的语法格式如下所示。DIMEN
4、SION(下标下界:下标上界,):数组名,类型说明:数组名,该定义形式通过DIMENSION语句直接说明了数组的维数和维的范围。这种形式定义的数组全部具有相同的维数和大小。如下代码表示了如何采用上述形式进行数组的定义。DIMENSION(10,4:10):A,B,NINTEGER:AREAL(8):N,9.1.4 定义形式四,第四种数组定义形式的语法格式如下所示。类型说明,DIMENSION:数组名(下标下界:下标上界,),类型说明,DIMENSION(下标下界:下标上界,):数组名,该定义形式可以说是前三种定义形式的综合形式。通过在DIMENSION语句前引入类型说明来显式的说明数组的数据类
5、型。下列代码演示了此种形式的数组定义。REAL,DIMENSION:I(10),M(10,5)INTEGER,DIMENSION(10):A,C,9.1.5 数组定义的特点,上述数组定义的形式中,中括弧内的部分可有可无。数组定义语句必须出现在所有可执行语句之前。除了上述基本的定义形式外,在Fortran77中可以使用COMMON语句,在Fortran90中可以用POINTER语句、ALLOCATABLE语句等对数组定义进行加强。在前面所述的四种定义形式中,定义形式因简洁直观而常见于实际使用中。此外,如下问题是在实际编程中应该注意的。在前面所述的数组定义中,I(10)、M(10,5)、A、C等称
6、为数组说明符。在同一个说明语句中有多个数组说明符时,用逗号进行分隔。数组说明符中的I、M、A、C等是数组名,其取名规则与变量相同并且不应与程序中的其他变量同名。在同一个程序单元中,一个数组名只允许定义一次,不能重复定义。例如下面的数组定义是错误的。INTEGER:A(10),A(10,20),9.2 数组的引用方式,数组经过定义之后,就可以在程序中使用了。在Fortran77标准中,数组只允许在输入输出语句中进行整体操作。在其他场合,只能对数组的元素通过下标索引的方式逐个进行操作。到了Fortran90标准,这一限制被大大放宽了。数组除了能够进行整体操作以外,还能对数组中的片断和数组的整体进行
7、操作。这进一步增强了Fortran语言在数值处理方面的能力。Fortran中数组的引用方式可以概括为以下几种:,9.2.1 引用数组元素,引用数组元素的语法格式如下所示。数组名(下标,)这种引用方式通过下标索引来对数组中的每一个元素进行操作。它是Fortran中最为传统的一种引用方式。采用这种方式进行引用时,下标的值不能超出数组定义时的下标上下界。目前市面上绝大部分的Fortran编译器都会提供在编译时进行数组下标越界检查的功能。而其他计算机语言的编译器,如C/C+编译器往往不提供这样的功能,需要程序员自行检查代码中是否存在数组越界的行为。,9.2.2 引用数组整体,引用数组整体的语法格式如下
8、所示。数组名这种引用方式通过数组名来对数组进行整体操作。这种引用方式是Fortan90中新增的,大大提高了程序编写的灵活性和简单性。我们对前一个例程TEST0901进行修改,通过整体引用来对数组进行赋值。TEST0902.F90!引用数组整体的范例PROGRAM TEST0902 IMPLICIT NONE!变量定义 REAL:A,B(5,5)READ(*,*)A!数组整体引用 B=AEND PROGRAM TEST0902,9.2.3 引用数组片断,引用数组片断的语法格式如下所示。数组名(下标范围,)在这种引用方式中,数组中的元素可以用过数组片断来进行引用。当需要给数组中的不同片断的元素赋予
9、不同数值时,这种引用方式非常方便。来看下面一个例子。TEST0903.F90!引用数组片断的范例PROGRAM TEST0903 IMPLICIT NONE!变量定义 REAL:A1,A2,A3,A4,A5,B(5,5)READ(*,*)A1,A2,A3,A4,A5!数组片断的引用 B(1,1:5)=A1 B(2,1:5)=A2 B(3,1:5)=A3 B(4,1:5)=A4 B(5,1:5)=A5END PROGRAM TEST0903,9.3 数组的存储,尽管在Fortran语言中,允许程序员声明维数高达7维的数组来使用,但是计算机的内存却只是一维的。所以不管声明的数组有几维,数组在内存中
10、都是以一维的方式来进行存储。数组中元素在计算机内的存储顺序同时也被用作输入/输出时确定其中的元素数据在进行操作时的先后顺序。,9.3.1 数组的存储结构,Fortran中,一维数组在计算机内存中的存储是最简单的一种情况。在逻辑结构上,一维数组可以看成是由一系列数组元素组成的一个单列数据表。数组中每个元素的下标就确定了此元素在数据表中的位置。下标越小,在数据表中的位置就越靠前。在计算机内存中,一维数组占据一片连续的存储单元,单个元素在内存中的位置就是其逻辑结构中的位置。,9.3.2 数组存储结构的应用,目前的计算机硬件体系结构决定了在读取大批量数据时,如果这一批数据都位于临近的内存中时,读取操作
11、会执行得较快。在编写程序时,如果想要提高执行效率,就应该对数据在计算中的保存方式和读取方式有一定的了解。只有了解了数据在计算内的存储结构,才能在编写程序的时候做到有的放矢。这样编写出来的程序在数据的存取效率上才能较高。需要注意的是,尽管Fortran中的数组是按“列元素优先”的规则进行存储的,但是C语言中的数组则是按照“行元素优先”的原则进行存储,并且C语言中数组的下标下界固定是从0开始的。在编写相关的程序时,应该注意到这一差别。Fortran语言中,使用DO循环进行高效率数组操作的代码写法可能在C语言中恰恰是最低效的。比如下面的程序段在Fortran中能够得到较好的执行效率:DO J=1,5
12、 DO I=1,3 Sum=Sum+A(I,J)ENDDO,9.4 数组的类型,根据数组在定义时的特征,比如数组的秩、数组的形状和每一维的大小,可以将数组划分为好几种类型。这些不同类型的数组在程序单元中如何使用?在哪些程序单元中使用?有什么特点?本节将针对这些问题进行逐一介绍。,9.4.1 显形数组,显形(Explicit-shape)数组是Fortran中最简单、最容易理解的一种数组类型。顾名思义,这种类型的数组在定义阶段就通过数组定义语句明确的规定了所有特征,比如数组的秩、数组的维数、每一维的长度和上下界。通过这种方式定义的数组具有确定的形状和大小,在程序运行过程中不允许再对数组的任何特征
13、进行改变。需要注意的是,在显形数组的维说明中,还允许使用整型变量或整型表达式来定义维的上下界。这涉及到两种特殊的显形数组,会在随后的小节中进行介绍。,9.4.2 特殊的显形数组自动数组,自动数组(Automatic Array)是显形数组的一种特殊形式,这种形式的显形数组只能是过程中的局部变量。使用自动数组时最好在过程中加以声明,并且数组中至少有一维的上下界是不确定的整型变量或整型表达式。在调用过程时,自动数组中不确定的上下界首先通过整型变量或整型表达式求出。这样,整型变量或整型表达式的值在过程中发生的变化,就不会影响到数组中的上下界。,9.4.3 特殊的显形数组可调数组,可调数组(Adjus
14、table Array)也是显形数组的一种特殊形式,这种类型的显形数组只能是过程中的一个哑元。可调数组中至少有一维的上下界不是常数,这个维的上下界只有当过程被调用时才能最终确定。并且该维的上下界表达式中的整型变量可以是通过过程传递的哑元,也可以是通过COMMON语句中传递的整型常量或变量。和自动数组类似,过程内部对维界参数的赋值不会改变数组中该维的上下界。,9.4.4 显形数组的不足,显形数组是数组应用的基础,其中的自动数组和可调数组能够提供非常灵活的数组应用。比如自动数组在处理具体数量未知的大笔数组数据时,能够提供相当好的解决方案。但是有一点需要注意,由于自动数组和可调数组都是通过过程来使用
15、的,因此过程的一些特点也会影响到这两种数组的使用。比如使用自动数组时,过程在计算机中的堆栈限制会妨碍可使用的自动数组的大小。这种情况可以通过在执行TEST0906时,将变量I设置成一个大数(比如100000)来观察到,此时屏幕上的打印信息如下:Input the value of I:100000forrtl:severe(170):Program Exception-stack overflowImage PC Routine Line SourceTEST0307.exe 004011DB Unknown Unknown UnknownTEST0307.exe 0040110A Unkno
16、wn Unknown UnknownTEST0307.exe 0043FCD9 Unknown Unknown UnknownTEST0307.exe 00428FF9 Unknown Unknown Unknownkernel32.dll 7C816FD7 Unknown Unknown UnknownIncrementally linked image-PC correlation disabled.,9.4.5 假定形状数组,假定形状(Assumed-shape)数组是一种在过程中使用的特殊类型数组,这种类型的数组借助过程中的哑元从实际传递到过程中的数组获得自身的形状参数。假定形状数组的
17、秩由数组定义中冒号“:”的个数来决定,其一般形式如下:类型声明 数组名(下界:,下界:.)如果在定义时不指定维的下界值,则默认这一维的下界值为1。维的上界值等于过程调用中实参数组对应维的长度加上定义中规定的下界值再减去1。假定形状数组与可调数组的区别非常细微:可调数组是一种显型数组,在定义时必须指定维的上界(尽管这个上界可以是变量或表达式);而假定形状数组在定义时是不能指定维的上界的。来看这样一个代码段:SUBROUTINE ASSUMEDSHAPE(A)REAL A(:,:,:)END SUBROUTINE ASSUMEDSHAPE,9.4.6 假定大小数组,假定大小(Assumed-siz
18、e)数组也是一种在过程中使用的特殊类型数组的哑元,这种类型的数组借助过程中的哑元从实际传递到过程中的数组来获得自身的大小。1假定大小数组的定义:假定大小数组在声明时,除了最后一维的上界以外,其它所有特征(比如数组的秩、维的长度和维的上下界等)都必须明确指定。声明假定大小数组的一般形式如下:类型说明 数组名(维说明符,维说明符,.下界:*)2假定大小数组的应用,9.4.7 延迟形状数组,延迟形状(Deferred-shape)数组是Fortran 90/95标准中才开始引入的特殊类型数组,这种类型的数组在声明时并不制定数组的维界,具体的维界需要在程序执行过程中才能确定。延迟形状数组的典型代表就是
19、数组指针和可分配数组。声明延迟形状数组时,数组的秩由冒号“:”来确定,但每一维的长度是未知的。数组的维界和形状在程序执行过程中给延迟形状数组分配存储空间之后才能决定。可分配数组可以通过ALLOCATABLE语句、DIMENSION语句、TARGET语句或在类型声明中使用ALLOCATABLE属性来进行说明;而数组指针则由POINT语句或在类型声明中使用POINTER属性来进行说明。数组指针的边界和形状通过指针赋值语句指向目标之后进行确定,或者通过ALLOCATE语句直接进行指针的空间分配;而可分配数组的边界和形状则只能通过ALLOCATABEL语句来进行指定。,9.5 数组的动态分配,所谓数组
20、的动态分配就是指数组的大小、形状等特征是在程序运行中动态的确定,而不是在程序声明段就确定好了的。数组的动态分配能给程序设计提供更大的灵活性。本节就将介绍有关数组动态分配的有关内容。,9.5.1 自动数组与可分配数组,从存储状态来说,数组可以划分为静态数组和动态数组两种。如果数组是静态的,那么在编译阶段就会为数组分配好固定的储存空间,这些存储空间在程序执行过程中会一直保留的,直到程序退出时才会被释放。程序运行过程中,静态数组的大小不会发生改变。静态数组的一个主要缺陷在于,即使数组已经不再使用,仍然会占据分配给它的内存空间,这就造成了系统资源的浪费。如果计算机的内存资源有限,这会使得其他程序的可用
21、内存资源减少。最严重的情况是可用内存资源不足,这将导致程序执行错误。,9.5.2 可分配数组的分配与释放,在实际的程序中,往往会碰到这样的问题:一些数组的大小在程序执行之前并不知道具体的大小,只能在程序运行的过程中才能确定。那么如何解决这类问题呢?一个办法就是为程序声明一个足够大的数组,大到将数据一股脑全装进去后还有富裕。但是这又会造成存储空间的浪费,在过去386、486的时代,浪费宝贵的内存无疑就是犯罪。另一种办法就是前面提到过的自动数组,这需要用到过程的概念和良好的程序设计结构。如果碰到有些数组需要作为全局变量在不同的过程中进行处理的情况,就只好采用开一个大数组的办法来解决。为了更有效的利
22、用计算机中的内存,Fortran 90/95标准中正是引入了可分配数组的概念。通过ALLOCATE语句可以动态的创建可分配数组,使内存和对象可以在程序开始运行之后才建立起相互联系。,9.5.3 可分配数组的应用实例,下面的代码实例演示了可分配数组在程序中的应用,以加深对可分配数组的理解。(详细内容请参照本书),9.6 数组赋值,当数组配置好内存空间后,可以通过赋值语句或是数组构造器为数组中的元素进行赋值。Fortran语言中,数组的赋值可以通过赋值语句、DATA语句和数组构造器这三种手段来进行。,9.6.1 数组赋值语句,首先介绍数组赋值语句。数组赋值语句是Fortran 90/95标准中新增
23、加的数组赋值手段。数组赋值语句的基本形式为:数组对象=value其中,数组对象代表数组名或数组片段,value表示数组表达式或者标量。当value为数组表达式时,必须和数组对象具有相同的形状(即维数相同、每维长度相同,但上下界可以不同);当value大小为0或者是长度为0的字符型变量时,则没有值赋给数组对象;当value为标量时,会把value处理成与数组对象相同的形状,此时数组对象的每个元素均等于标量value的值。数组表达式中允许使用“+”、“-”、“*”、“/”、“*”等内部算术操作符。,9.6.2 数组构造器,数组构造器是由括号和斜线对之间的一系列数值组成,其一般形式为:数组名=(/取
24、值列表/)其中,取值列表可以是标量,隐式DO循环或者任意秩的数组。取值列表中所有数值的类型都应该相同,数值之间以逗号分隔。如果取值列表中出现了数组,则它的值是按“列元素优先”的规则来赋给目标数组变量。数组构造器的标识“(/”和“/)”在书写时要注意,括弧和撇号之间不能有空格。下面来看一些实例。MN=(/1,3,5,7,9/)!标量表示AB=(/B(2,1:5),B(3:7,7:9)/)!数组表示CC=(/(I,I=1,4)/)!隐DO循环DE=(/10,A(2:7),(I,I=1,4),7/)!混合表示,9.6.3 DATA语句,DATA语句从Fortran 77时代开始就已经用于数组的赋值,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- FORTRAN中的数组 2 FORTRAN 中的 数组
链接地址:https://www.31ppt.com/p-6505865.html