【Fortran】初级数组(⼀维数组)
⽬录
Fortran中的⼀维数组
数组是⼀组类型完全相同、且⽤单个名字来引⽤的变量或常量。
1) 数组声明
在声明数组⼤⼩时,应使⽤参数来声明,以保证程序后续易修改。
1. ⼀维数组:长度与数组中个数相同,使⽤( )可以访问具体数值。声明语句如:
INTEGER,DIMENSION(10)::number  ! 定义长度为10的整数型数组number,同理可换成其它类型
2. 常量数组是指完全由常量组成的数组,可以通过数组构造器来定义。数组构造器的形式有(/ /)和[ ],以下两个数组是等效的:
(/ 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. ]
2. 元素较多,且有规律的,可结合DO循环语句,如:
REAL , DIMENSION(100)::array2
DO i = 1,100
array2( i ) = REAL( i )
END DO
3. 数组中所有元素均为同⼀值,可直接赋值,如:
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. ]
2. 元素较多,且有规律的,可结合隐式DO循环语句,如:
REAL , DIMENSION(100)::array5 = [(i , i =1 , 1000) ]
3. 数组中所有元素均为同⼀值,可直接赋值,如:
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为增量,其中i、j和m可以部分甚⾄全部缺省。具体例⼦如下:
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)  ! 输出
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)。具体不详述。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。