欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【Fortran】一维数组(初级)

程序员文章站 2023-12-25 22:46:21
...


Fortran中的一维数组

数组是一组类型完全相同、且用单个名字来引用的变量或常量。

1) 数组声明

在声明数组大小时,应使用参数来声明,以保证程序后续易修改。

  1. 一维数组:长度与数组中个数相同,使用( )可以访问具体数值。声明语句如:
INTEGER,DIMENSION(10)::number  ! 定义长度为10的整数型数组number,同理可换成其它类型
  1. 常量数组是指完全由常量组成的数组,可以通过数组构造器来定义。数组构造器的形式有(/ /)[ ],以下两个数组是等效的:
(/ 1 , 2 , 3 , 4 , 5 /)
[ 1 , 2 , 3 , 4 , 5 ]

2) 数组初始化

在使用数组之前,一定要先对其初始化。

初始化方法主要有三种:

  1. 用赋值语句初始化;

    1. 元素较少的,直接赋值,如:
    REAL , DIMENSION(10)::array1
    array1 = [1. , 2. , 3. , 4. , 5. , 6. , 7. , 8. , 9. , 10. ]
    
    1. 元素较多,且有规律的,可结合DO循环语句,如:
    REAL , DIMENSION(100)::array2
    DO i = 1,100
    	array2( i ) = REAL( i )
    END DO
    
    1. 数组中所有元素均为同一值,可直接赋值,如:
    REAL , DIMENSION(10)::array3
    array3 = 1.0     ! 所有元素均为1.0
    
  2. 使用类型声明语句初始化;

    1. 元素较少的,直接声明,如:
    REAL , DIMENSION(10)::array4 = [1. , 2. , 3. , 4. , 5. , 6. , 7. , 8. , 9. , 10. ]
    
    1. 元素较多,且有规律的,可结合隐式DO循环语句,如:
    REAL , DIMENSION(100)::array5 = [(i , i =1 , 1000) ]
    
    1. 数组中所有元素均为同一值,可直接赋值,如:
    REAL , DIMENSION(10)::array6 = 1.0  ! 所有元素均为1.0
    
  3. READ语句初始化;

3) 数组下标

N个元素的数组通常用下标1,2······,N来访问,即默认是从1开始,对应的声明形式如: REAL , DIMENSION(N)::array
此外,可以指定下标的取值范围,即在声明语句中声明下标的起始值和结束值,对应的形式如:REAL , DIMENSION(a:b)::array,下标从a开始,至b结束,元素总个数为b-a+1
需注意的是,索引时下标不能超过定义的范围,否则可能中断,也可能返回一个非期望值(可能会访问至该数组相邻内存位置的其它数值)

4) 数组操作

  1. 整体数组
    当两个数组的结构(行和列数)相同时,可用内置操作符(如+)进行操作,此时两个数组的下标值不一定要相同。如:

    PROGRAM array_test
    IMPLICIT NONE
    REAL , DIMENSION(4) :: a = [1. , 2. , 3. , 4.] 
    REAL , DIMENSION(-1:2) :: b = [5. , 6. , 7. , 8.]   ! 下标不一致也不影响结果
    REAL , DIMENSION(4) :: c    
        
    c = a + b    
    WRITE(*,*) c
    WRITE(*,*) -c       ! 所有元素取反号
    
    STOP
    END PROGRAM array_test
    

    相应结果为:

       6.000000       8.000000       10.00000       12.00000
      -6.000000      -8.000000      -10.00000      -12.00000
    
  2. 部分数组
    相当于是切片,具体语句为array(i:j:m)i为起始下标,j为结束下标,m为增量,其中ijm可以部分甚至全部缺省。具体例子如下:

    PROGRAM array_test
    IMPLICIT NONE
    REAL , DIMENSION(10) :: a 
    INTEGER::count,i
    
    count = 1
    DO i=1,20,2
        a( count ) = i
        count = count + 1
    END DO    
    
    WRITE(*,100) a    ! 结果很直观,不过多解释了
    WRITE(*,100) a( : )
    WRITE(*,100) a( 2 : 7 )
    WRITE(*,100) a( 2 :  )
    WRITE(*,100) a(  : 7 )
    WRITE(*,100) a( : : 2)
    
    100 FORMAT(*(F4.1,1X))  ! *号表示无限循环使用
    
    STOP
    END PROGRAM array_test
    

    相应结果为:

     1.0  3.0  5.0  7.0  9.0 11.0 13.0 15.0 17.0 19.0
     1.0  3.0  5.0  7.0  9.0 11.0 13.0 15.0 17.0 19.0
     3.0  5.0  7.0  9.0 11.0 13.0
     3.0  5.0  7.0  9.0 11.0 13.0 15.0 17.0 19.0
     1.0  3.0  5.0  7.0  9.0 11.0 13.0
     1.0  5.0  9.0 13.0 17.0
    

5) 数组输入和输出

  1. 逐个变量操作,如

    REAL , DIMENSION(5) :: a 
    WRITE(*,100)  a(1) , a(2), a(3) , a(4) , a(5)   ! 输出
    READ(*,100)  a(1) , a(2), a(3) , a(4) , a(5)   ! 输入
    100 FORMAT(5F4.1) 
    

    但当有多个数据时,操作麻烦。

  2. 隐式DO循环
    隐式DO循环作为控制变量的函数来多次输出/输入数组数据,语句为:
    WRITE(unit,format) (arg1,arg2,...,index = istart,iend,incr)
    READ(unit,format) (arg1,arg2,...,index = istart,iend,incr)
    可将上面例子写成:

    REAL , DIMENSION(5) :: a 
    INTEGER::i
    WRITE(*,100)  (a(i),i=1,5)
    READ(*,100)  (a(i),i=1,5)
    100 FORMAT(5F4.1) 
    

    另一个例子:

    REAL , DIMENSION(5) :: a = (/1.,2.,3.,4.,5./)   
    INTEGER::i
    WRITE(*,100)  (a(i),2*a(i),3*a(i),i=1,5) ! 每个i有三个数,共有15个数
    100 FORMAT(15F5.1) 
    

    相应结果为:

      1.0  2.0  3.0  2.0  4.0  6.0  3.0  6.0  9.0  4.0  8.0 12.0  5.0 10.0 15.0
    

    如果将输出格式改成FORMAT(5F5.1) ,(具体原因见显式与隐式DO的区别)则输出结果为:

      1.0  2.0  3.0  2.0  4.0
      6.0  3.0  6.0  9.0  4.0
      8.0 12.0  5.0 10.0 15.0
    
  3. 嵌套的隐式DO循环
    最里面的括号为内层,外面的为循环外层,如例子中的j是内层循环,i是外层循环:

    INTEGER::i , j
    WRITE(*,100) (( i , j , j = 1 , 3 ) , i =1 , 2)
    100 FORMAT(I1,1X,I1) 
    

    相应结果为:

    1 1
    1 2
    1 3
    2 1
    2 2
    2 3
    
  4. 显式DO循环与隐式DO循环的区别
    以输出WRITE语句为例:
    ①显式操作:

    PROGRAM DO1_test
    IMPLICIT NONE
    INTEGER , DIMENSION(5) :: a = (/1,2,3,4,5/)   
    INTEGER:: i 
    
    DO i=1,5
        WRITE(*,100) a(i) , 2*a(i) , 3*a(i)
        100 FORMAT(6I3) 
    END DO
    
    STOP
    END PROGRAM DO1_test
    

    ②隐式操作:

    PROGRAM DO1_test
    IMPLICIT NONE
    INTEGER , DIMENSION(5) :: a = (/1,2,3,4,5/)   
    INTEGER:: i 
    
    WRITE(*,100) (a(i) , 2*a(i) , 3*a(i) , i=1,5)
    100 FORMAT(6I3) 
    
    STOP
    END PROGRAM DO1_test
    

    相应结果为:
    ①显式结果:

      1  2  3
      2  4  6
      3  6  9
      4  8 12
      5 10 15
    

    ②隐式结果:

      1  2  3  2  4  6
      3  6  9  4  8 12
      5 10 15
    

    区别
    对于显式循环,每一次循环会执行一条WIRTE语句,共有五条WIRTE语句,每一条WIRTE语句上只有三个变量,因此每次只会使用格式描述符(6I3)中的前三个,即实际格式为FORMAT(3I3)
    对于隐式循环,尽管会执行五次,但是只有一条WIRTE语句,变量个数大于格式数目,格式可以重复使用,因此每六个变量使用一轮格式,再进行换行。

  5. 整体和部分输出
    同样,在I/O语句中允许切片操作array(i:j:m)。具体不详述。

上一篇:

下一篇: