Fortran声明变量的同时也可以加一些限定词以表明这个变量的属性。例如上次教程中提到的parameter关键字就可以限定变量为常数。这个关键字在定义变量时类似于C/C++中的const关键字,需要在声明的同时赋初值,并且之后不能被修改。声明方式如下:

1
integer, parameter :: var = 5

这里定义了一个整数常量var,并赋初值为5。

指针

Fortran90/95标准中首次引入了指针(pointer)的概念。这里和C/C++不同的是,若要声明一个变量是指针,那么它的指向目标也要有目标(target)属性的修饰。Fortran中的指针更像是C/C++中的引用,或者说是变量别名。

1
2
3
1    real, pointer :: p
2 real, target :: var
3 p=>var

上述代码声明了一个浮点型指针p和浮点型变量var,并将p指向了var。正如上所说p和var实际上是指向同一块内存空间的,其中一个变量的指若是发生了变化,那另一个变量的值也会随着发生变化。当然,这里还体会不到Fortran中指针功能存在的必要性。

数组

接下来我们讲讲Fortran中数组的声明方式,拿一维数组举例,若要声明一维数组可以才用如下的方式:

1
2
3
4
5
6
7
8
9
1    real :: array1(5)
2 real, dimension(5) :: array2
3 real :: array3(1:5)
4 real :: array4(-5:5)
5 real :: array5(5) = [1,2,3,4,5]
6 real :: array6(5) = (/1,2,3,4,5/)
7 data array1 /1,2,3,4,5/
8 real :: array8(5) = (/ (i, i=1,5) /)
9 real :: array9(5,5)

上述代码前两行通过两种方式定义了一个长度为5的浮点型数组,Fortran默认指标是从1开始,也就是说第一行和第三行是等价的。第二行的这种定义方式在要大量定义相同数组的时候可以简化代码。另外Fortran中数组的指标可以从负数开始,如第四行就定义了一个指标从-5到5的长度为11的数组,这种设定在科学计算中是相当方便的。数组在定义的同时方可利用第5行和第6行的方式进行初始化,或在声明变量之后利用data关键字去初始化,也可利用隐式循环初始化,这个会在循环专题中再提到。第9行定义了一个5*5大小的二维数组,若要定义更高维的数组,只需要多加逗号即可,gfortran最高支持7维数组声明。

和C/C++一样,有时候我们事先并不知道所需数组的大小,这就要求我们需要去动态生成所需大小的数组。C++11标准中加入了new关键字,可以很方便的动态生成数组。Fortran90/95标准中也引入了类似的功能,如下:

1
2
3
4
5
1    real, allocatable, dimension(:,:) :: array
2 logical :: chi
3 allocate(array(5,5))
4 chi = allocated(array)
5 deallocate(array)

第一行定义了一个动态分配的2维数组,完了利用allocate函数进行动态分派内存,例如这里将array动态分配为了5*5的数组。allocated函数是用于判断声明过的可动态分配的数组是否已经分配,若已分配则返回.true.,否则返回.false.。最后deallocate函数是释放数组所占用内存用的。Fortran中最强大的功能莫过于矩阵运算了,这里类似于MATLAB,可以对数组进行整体操作,可以简化很多代码。原生的向量化数组操作可以避免不少麻烦,关于数组的运算,我将放到下次讲解。

Fortran中除了这些属性关键字以外,还有save,value,volatile,optional,intent等,这些会穿插在剩余教程中讲解。

写在最后

这里补充一些老的并不建议使用的用法。

1
2
real*8 var1
double precision var2

第一行表示的是声明一个双精度浮点型变量var1,这种声明方式等价于real(8),第二行是在I-N规则(ijklmn)下声明变量为双精度的方式,由于不建议使用I-N规则,所以这种声明方式是不提倡的,能看懂老代码即可。另外需要说明的是Fortran是不区分大小写字母,也就是说定义变量var和VAR是一回事,这个是历史遗留问题,最初Fortran是只能写大写字母的。另外合法的Fortran变量名不能以数字开头,除数字和字母外,还可包含下划线。