【转】Fortran数组学习

类别:    标签: 编程 fortran   阅读次数:   版权: (CC) BY-NC-SA

2012-07-26 11:10:04

原文: 第五章: 数组 数组类型与定义

两种变量:标量+数组. 标量维数为0, 数组维数>=1.

数组的定义

类型相同的一组标量数据的有序集合

数组元素类型必须相同, 这些元素按某种确定方式排列

数组的维数

数组声明

声明时数组的维数必须指定的, 大小和形状是否需要指定视数组的形式而定

数组的引用

数组的下标列表有两种:三元下标和向量下标.

三元下标[下界]:[上界][:步长]

用三个值分别代表数组片段的下界, 上界和步长, 以上升或下降的顺序指定数组元素.

向量下标

利用一个一维整数数组(即向量)来指定数组元素

数组类型

  1. 显式形状(Explicit-shape)数组:指定了维数和每一维的维长, 维下界是可省略, Array([维下界:]维上界[,[维下界:]维上界]…)

    例:integer M(10,10,10), K(-3:6,4:13,0:9)

    • 维界可以是常数或变量.
    • 在过程(函数和子程序)中, 数组的上界和下界可以由变量或表达式指定.
    • 使用变量或表达式的数组是自动数组和可调数组.
  2. 自动(Automatic)数组

    • 显形数组的一种, 它是过程中的局域变量
    • 自动数组必须在过程中加以声明, 并且它的上下界是不定的表达式.
    • 在调用过程时, 上下界通过变量或表达式求出.
    • 过程中其后的变量或表达式值的变化不会对数组的上下界产生影响.

    # Language: fortran
     subroutine example(N,R1,R2)
         dimension A(N,5), B(10*N)
         ……
         N=IFIX(R1)+IFIX(R2)
         ……
     end
    

    此例中的A和B都是自动数组. 子程序被调用时, 数组A和B的上界通过传入的变量N来确定, 而以后N的值的变化对A和B的大小不会有影响.

    # Language: fortran
     subroutine sub1(M, N)
         integer M, N, lower
         common/bound/lower
         ……
         integer auto_array1(N)
         integer auto_array2(lower:N)
         integer auto_array3(20,N*M/2)
         ……
     end subroutine
    
  3. 可调(Adjustable)数组

    • 可调数组也是显形数组的一种, 它是过程的一个哑元, 至少有一个维界不是常数, 这个维界当过程被调用时才被确定.
    • 其维界表达式中的变量是哑元, 或者是通过COMMON语句中传递的常量.
    • 注意多维可调数组的维界表达式必须与调用时的维界相符.

    # Language: fortran
         dimension A1(10,35), A2(3,56)
         ……
         sum1=the_sum(A1, 10, 35)
         sum2=the_sum(A2, 3, 56)
     end
    	
     function the_sum(A, M, N)
         dimension A(M, N)
         sumx=0.0
         do j=1,N
             do i=1,m
                 sumx=sumx+A(i,j)
             end do
         end do
         the_sum=sumx
     end function
    

    其中哑元M,N控制着可调数组的大小.

    # Language: fortran
         dimension Array(9,5)
         L=9
         M=5
         call sub(Array,L,M)
     end
    	
     subroutine sub(X,i,j)
         dimension X(-i/2:i/2,j)
         X(i/2,j)=999
         j=1
         i=2
     end
    

    可调数组的维界X(-4:4,5)在调用过程时被确定后, 过程内部对维界参数的赋值不会改变维界值.

  4. 假定形状(Assumed-shape)数组

    • 这种数组是在过程中的哑元, 它从实际传递过来的数组获得形状参数. 假定形状数组的秩由冒号的个数决定.
    • 它的一般形式是:([下界]:[,[下界]:]…). 如果不指定下界, 则默认值为1. 上界值=过程调用时实参数组对应维的长度+下界值-1.
    • 注意它与可调数组的区别在于,可调数组属于显型数组(必须指定上界)的范围, 而假定形状数组的上界是不能指定的.

    # Language: fortran
     subroutine assumed(a)
         real a(:,:,:)
     end
    

    此时数组a的秩为3, 但每一维的长度待定. 当过程被调用时a将从传递到过程的数组获得形状

    real x(4,7,9)

    call assumed(x) 于是a获得了数组维界(4,7,9), 实际数组和假定形状数组的值必须相同. 如果上面过程中数组声明了a(3:,0:,-2:), 以哑元x(4,7,9)调用过程时, 数组a的实际维界是a(3:6,0:6,-2:6).

    应用假定形状数组为哑元的过程时必须有显式的接口INTERFACE语句.

    # Language: fortran
     interface
         subroutine sub(m)
             integer m(:,1:,5:)
         end subroutine
     end interface
    	
     integer L(20,5:25,10)
    	
     call sub(L)
    

    在此例中数组M的维界是(1:20,1:21,5:14).

  5. 假定大小(Assumed-size)数组

    • 这种数组是在过程中的哑元, 它从实际传递过来的数组获得数组大小.
    • 除了最后一维的上界以外, 其它所有特征(秩, 长度和维界)都必须指定.
    • 声明一个假定大小数组时, 最后一个的上界用星号表示. 它的一般形式是:([显型维界,][显型维界,]…[下界:]).

    # Language: fortran
     subroutine assume(a)
         real a(2,2,*)
     end
    

    假定大小数组的秩和形状可以和实际传入的数组不同, 传入的数组只确定它的大小. 实际数组的元素按列传递给假定大小数组, 假定大小数组也按列接收. 接受的过程中假定大小数组的最后一维的长度会改变来接受所有传递进来的数组元素, 于是最终给出数组的大小. 如上例子中的assume子程序, 如果以数组x为哑元来调用的话,

    real x(7)

    call assume(x)

    则数组X的元素与数组A的对应顺序是:

    X(1):A(1,1,1)
    X(2):A(2,1,1)
    X(3):A(1,2,1)
    X(4):A(2,2,1)
    X(5):A(1,1,2)
    X(6):A(2,1,2)
    X(7):A(1,2,2)

    其中数组A的最后一维没有必要成为完整的维, 所以数组A始终没有确定的形状. 因为假定大小数组没有形状, 所以这样的数组不能仅仅通过名称来向其它过程传递.

    假定大小数组可以分解成确定的数组片段. 如上例中的数组A, 可分为三个片段:A(1:2,1:2,1)和A(1:2,1,2)以及A(1,2,2).

    假定大小数组的秩是完全确定的维数+1. 上例中数组A的秩为3, 尽管A的第三维不是完整的.

  6. 延迟形状(Deferred-shape)数组

    用来声明可分配数组, 维数由冒号确定, 但维长只有在分配数组才被确定.

    • real, allocatable:: A(:,:,:)
    • integer, allocatable, target:: K(:)

    可分配数组可由下列方式声明:使用allocatable语句、dimension语句、target语句或在类型声明中使用allocatable属性. 如果迟形数组以dimension语句或target语句声明, 则在其它语句中必须给出allocatable属性.

    在迟形数组的大小、形状和维界没有确定之前, 其任何部分都不能被引用, 可分配数组的大小、形状和维界在allocate语句执行时才被确定.

    • integer,allocatable:: A(:,:)
    • real,allocatable,target:: B(:,:), C(:)
    • allocate(A(2,3), C(5), B(size(C),12))
随意赞赏

微信

支付宝
◆本文地址: , 转载请注明◆
◆评论问题: https://jerkwin.herokuapp.com/category/3/博客, 欢迎留言◆


前一篇: 我的博客文本编辑器——EmEditor
后一篇: 【转】Fortran的奇淫技巧

访问人次(2015年7月 9日起): | 最后更新: 2017-08-15 19:57:07 UTC | 版权所有 © 2008 - 2017 Jerkwin