Fortran 第六讲
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
6.1.1 对整个数组的操作
不带下标的数组名引用,视为对整个数组的引用 INTEGER :: a(5) WRITE (*,*) a 会依次输出a的每个元素值
a=1 将a的每个元素赋值1
结构一致的数组可以直接算术运算 INTEGER :: a(5),b(5),c(5) a=1 b=2 c=a+b a和b对应的元素相加后放到c对应的位置 c=a-b c=a*b c=a/b
6.2.3 变换内置函数
有一个或多个数组作为参数的函数,变换内置函 数操作整个数组 输出与输入参数可能没有相同的结构
RESHAPE(SOURCE,SHAPE) 这个上次课讲过了 将SOURCE的元素按照SHAPE重新构建一个新的数 组 RESHAPE((/1,2,3,4,5,6/),(/2,3/)) 将一维数组(1,2,3,4,5,6)构造为2X3的二维数组
动态分配一个二维数组 通过status返回分配状态 如果分配成功,status为0,否则不为0
总是使用STAT=status监视分配状态,以便准确知道 程序异常终止的原因
ALLOCATED()函数 ALLOCATED(array) 如果已经用ALLOCATE()给ARRAY分配了空间 那么函数返回值是.TRUE. 否则为.FALSE. 例: IF (ALLOCATED(array)) THEN array=1 ELSE WRITE(*,*) ‘Warning : Array not allocated!’ END IF
SUM (ARRAY,MASK) 计算ARRAY中MASK为真的元素的和。MASK为 可选的,如果不提供,计算数组中所有元素的和
TRANSPOSE(MATRIX) 将MATRIX转置后返回
更多的变换函数可以参考教材的附录A的数组函数 部分
这些函数都很有用,我们在以后的例程或习题会涉 及到一部分,请诸位养成查阅这一附录的习惯
释放内存:DEALLOCATE
使用可分配数组的程序或过程的最后应该释放内存 使这些内存可以再次使用 DEALLOCATE(arr1,[arr2,arr3,…,STAT=status]) 例: DEALLOCATE(arr1,STAT=status) 始终记得在使用完成后用DEALLOCATE释放内存
example: INTEGER :: info(9) info=(/1,-3,0,-5,-9,3,0,1,7/) WHERE (info>0) info=-info ELSEWHERE info=-3*info END WHERE WRITE (*,*) info
单行WHERE语句
WHERE (mask_expr) Array AssigΒιβλιοθήκη Baidument Statement
INTEGER::a(10) 以下部分应用的含义? a(:) a(3:7) a(3:7:2) a(3:) a(:7) a(::3)
INTEGER :: a(5,10) 以下部分数组的含义? a(1:3:2,3:5:1) a(:,1) a(:,:) a(:5:2,9::) a(3,:)
6.2 对数组使用Fortran内置函数
每个triplet叫一个三元组,由下面形式构成 下标1:下标2:下标增量 REAL::work(10,10) FORALL (i=1:10,j=1:10,work(i,j)/=0.) work(i,j)=1./work(i,j) END FORALL
6.5 可变大小数组
截止目前所讲的都是静态内存分配数组 每个数组的大小在编译的时候设定且不可更改 有什么缺点?
用于查询对象的属性 部分常用的数组查询函数 ALLOCATED(ARRAY) LBOUND(ARRAY,DIM) SHAPE(SOURCE) SIZE(ARRAY,DIM) UBOUND(ARRAY,DIM)
这些查询函数在将数组传递给过程时,非常有用
LBOUND(ARRAY,DIM) 如果没有DIM,返回数组ARRAY的所有下界,这 个返回值是一个一维数组 如果指定了DIM,返回一个标量,表示 DIM这个 维度的下界 INTEGER::a(3:5,3:6,0:7) LBOUND(a) LBOUND(a,1) LBOUND(a,3) UBOUND类似,只是表示上界 UBOUND(a,3)
6.1.2 内置函数对数组的作用
多数内置函数都接受数组作为输入参数 返回结果为数组 内置函数对数组的作用是逐个应用到数组的元素
REAL :: a(4)=(/-1.,2.,-3.,4./) a=ABS(a)
6.1.3操作部分数组
部分数组(局部数组): 下标用下标三元组(下标向量)来指定: 常见形式: 下标1:下标2:下标增量 以上三个部分构成一个三元组,都可以缺省 如果缺省下标1,那么默认为数组中本 维度第一 个元素的下标 如果缺省下标2,那么默认为数组中本维度最后一 个元素的下标 如果缺省下标增量,默认为 1
ALL(MASK) 如果数组MASK中的所有元素值都为真,逻辑函 数返回TRUE ANY(MASK) 如果数组MASK的任意元素值为真,逻辑函数返 回TRUE COUNT(MASK) 返回数组MASK中为真元素的个数
MAXLOC(ARRAY,MASK) 返回MASK为真对应的ARRAY中的元素的最大值 的位置,结果是带有一个元素的一维数组,这个 数组元素是ARRAY中的下标值,MASK是可选的 MAXVAL(ARRAY,MASK) 返回MASK为真对应的ARRAY中的元素的最大值 MINLOC(ARRAY,MASK) 参考MAXLOC MINVAL(ARRAY,MASK) 参考MINVAL
三大内置函数: 基本函数 查询函数 变换函数
6.2.1基本内置函数
使用标量参数的函数,也可以用数组作为参数 使用标量作为参数时,函数返回值是标量 使用数组作为参数,函数返回相同结构的数组 ABS LOG SIN LOG10 COS MOD TAN SQRT EXP
6.2.2 查询内置函数
SHAPE(SOURCE) 返回数组SOURCE的结构 INTEGER :: a(-3:7,0:8)
SHAPE(a) ?
SIZE(ARRAY,DIM) 如果给出了维度,返回该维度的宽度 否则返回数组中元素的个数
INTEGER :: a(-3:7,0:8) SIZE(a,1) SIZE(a) ? ?
WHERE(a<0) a=-a
6.4 FORALL结构
FORALL 结构也可以对部分数组元素操作 被操作的元素通过下标索引和逻辑条件进行选择 [name:]FORALL (in1=triplet1,[in2=triplet2,…,logical_expr]) statement 1 statement 2 … statement n END FORALL [name]
DOT_PRODUCT(VECTOR_A,VECTOR_B) 计算两个大小相等的向量的点积 参数是两个元素个数相等的一维数组
MATMUL(MATRIX_A,MATRIX_B) 计算两个矩阵的叉积 参数必须是两个可以叉乘的矩阵
MASK 与 mask_expr 在此后的学习中,经常会见到以上两个形式 MASK=mask_expr mask_expr是说明掩码的逻辑数组 这个数组的所有元素都是逻辑值 例: INTEGER :: a(5)=(/1,2,3,4,5/) LOGICAL :: b(5) b=a>3
Fortran程序设计
第六讲 数组(二)
回顾第五讲
数组 定义、改变下标范围的定义 三种初始化方法 和变量一样使用 数组在内存中是如何存储的
防止使用中产生数组的越界
在数组初始化中,引入隐式DO循环
隐式DO循环在IO语句中的应用
FORMAT进阶
第六讲
如何对整个数组或数组的一部分进行操作 如何对数组使用Fortran内置函数 WHERE语句的用法 FORALL结构的用法 如何定义可变大小的数组
6.3 WHERE结构
6.1中,我们学习了如何操作部分数组 INTEGER :: a(10) a(3:5)=3 将a(3),a(4),a(5)赋值为3
如果我们要对满足某个条件的所有元素进行操作 WHERE (a<0) a=ABS(a) END WHERE 将a中所有小于0的元素取绝对值
一般形式 [name:] WHERE (mask_expr1) 数组操作语句体1 ELSEWHERE (mask_expr2) [name] 数组操作语句体2 ELSEWHERE [name] 数组操作语句体3 END WHERE [name]
说明: WHERE结构中的每个mask_expr是一个逻辑数组, 它应该确保和数组执行语句中处理的数组具有同 样的结构。 WHERE结构使得语句体1中的操作或操作集用于 mask_expr1为TRUE的所有数组元素上,语句体2 中则作用于mask_expr1为FALSE而mask_expr2为 TRUE的所有数组元素上,最后,语句体3作用于 mask_expr1和mask_expr2均为FALSE的所有数组 元素上
解决方案是采用动态内存分配数组
实现方法: 分配:ALLOCATABLE和ALLOCATE() DEALLOCATE
例: INTEGER,ALLOCAT ABLE:: a(:) INTEGER :: i read (*,*) i ALLOCATE(a(i)) 分配了一个一维数组,数组大小从键盘输入
REAL,ALLOCATABLE :: a(:,:) INTEGER :: i=100,j=500,status ALLOCATE(a(i,0:j),STAT=status)