个人理解,欢迎指正
指针就是记录数据的内存地址的变量。指针可以指向单个变量,也可以指向数组。
数组是一个概念,是若干个类型相同的元素的有序集合。在Fortran语言中,数组中存放的元素,可以是整数,实数,复数,甚至结构体(或称自定义数据类型)。但是,在Fortran中,数组中存放的元素不能是指针。即不存在这样一个数组,该数组的每一个元素都是一个指针,分别指向不同的数组。
那么怎样才能实现,有一个数组,而数组中每一个元素都能指向其它数组呢?
因为数组中存放的元素可以是结构体,那么可以通过定义一个结构体,在结构体中定义一个指针变量来解决。
type containerclass(object), pointer :: obj
end type container
type(container), allocatable, dimension(:) :: objects
allocate (objects(0:num_objects))
objects(0)%obj => s1
其中,objects(0:num_objects)就是定义的结构体数组,数组中的第0个元素的obj分量(objects(0)%obj)指向一个变量s1,s1是类型为object的变量。
上式objects数组中的每一个元素都是指向单个变量的,那么如果需要结构体数组中的每一个元素都指向一个数组,则定义结构体中的指针变量需要定义为是指向数组的(下面第10行):
1 program ex12 implicitnone3 integer :: i,j4
5 !//声明目标数组work
6 real(RK),allocatable,target :: work(:,:)7
8 !//定义结构体类型qcontainer,该类型中的分量obj可以指向一个一维的数组
9 type qcontainer10 real(RK),pointer :: obj(:)11 end type qcontainer12
13 !//声明一个一维的的数组qtwork
14 type(qcontainer),allocatable :: qtwork(:)15
16 !//定义数组work并赋初值
17 allocate(work(2,3))18 do i=1,2
19 do j=1,3
20 work(i,j)=i*j**2*7
21 end do
22 end do
23
24 !//定义数组qtwork
25 allocate(qtwork(3))26
27 !//qtwork中第j个元素的object分量指向数组work的第j列
28 qtwork(j)%obj =>work(:,j)29
30
31 end program ex1
关于彭书中的“”指针数组“
彭国伦《Fortran95程序设计》书中275页上说,“指针也可以声明成数组”,并给了以下示例代码
1 program ex10042 implicitnone3 integer, pointer :: a(:)4 integer, target :: b(5)=(/ 1,2,3,4,5 /)5 !把指针数组a指向数组b6 a=>b7 ! a(1~5)=>b(1~5)8 write(*,*) a9 a=>b(1:3)10 ! a(1)=>b(1), a(2)=>b(2), a(3)=>b(3)11 write(*,*) a12 a=>b(1:5:2)13 ! a(1)=>b(1), a(2)=>b(3), a(3)=>b(5)14 write(*,*) a15 a=>b(5:1:-1)16 ! a(1)=>b(5), a(2)=>b(4), a(3)=>b(3), a(4)=>b(2), a(5)=>b(1)17 write(*,*) a18 stop19 end
这里用指针a表示了数组b。这告诉我们,指针不仅可以指向单个变量的内存地址,还可以指向数组。
但是需要注意的是,指针a(:)中的每一个变量a(i)都确定的表示了某一个单独的变量,而不是表示变量的集合的数组。即指针a(:)只能表示一个数组,不能同时表示多个数组的集合。
另外,需要注意,声明指针a的时候,可以说明a的形状,但不能指定a的数组大小。换句话说,声明指针a的时候,可以告诉编译器,a所指向的变量是几维的数组,但是不能告诉编译器,a所指向的数组是大小是100×100的。
第3行换成以下语句是非法的
!//非法的代码
integer, pointer :: a(5)
编译器错误提示是“ ALLOCATABLE or POINTER attribute dictates a deferred-shape-array.” 即声明变量时,allocatable或pointer的属性表明数组为假定形状数组。如果此时声明上述语句(即给了数组的大小),那显然矛盾。
总结
在Fortran中,指针可以指向一个数组或者一个数组中的一部分,但指针不能同时表示多个数组。
数组是若干相同类型元素的集合,但数组的元素不能是指针。
如果想实现一个数组,且数组的元素具有指针的功能,可以定义一个结构体类型的数组。
附录代码:
1 program test2 implicitnone3 integer i,j,k4 real,allocatable,target :: work(:,:)5
6 type qcontainer7 real,pointer :: obj(:)8 end type qcontainer9
10 type(qcontainer),allocatable :: qtwork(:) ,qtemp11
12
13 allocate(work(2,3))14 allocate(qtwork(3))15
16 !//初始化
17 do j=1,3
18 do i=1,2
19 work(i,j)=i*j**2*7
20 end do
21 end do
22
23 !//指针变量赋值
24 do j=1,3
25 qtwork(j)%obj =>work(:,j)26 end do
27
28 !//打印输入数组
29 print*,"input array:"
30 do j=1,3
31 print*,work(:,j)32 end do
33
34 !//打印指向的数组
35 print*,"point array:"
36 do j=1,3
37 print*,qtwork(j)%obj38 end do
39
40 !//置换
41 print*,"swap"
42 qtemp = qtwork(1)43 do j=1,2
44 qtwork(j) = qtwork(j+1)45 end do
46 qtwork(3)=qtemp47
48 !//输出置换结果
49 do j=1,3
50 print*,qtwork(j)%obj51 end do
52
53 deallocate(work)54
55
56 end program
输出结果:
input array:7.000000 14.00000
28.00000 56.00000
63.00000 126.0000point array:7.000000 14.00000
28.00000 56.00000
63.00000 126.0000swap28.00000 56.00000
63.00000 126.0000
7.000000 14.00000Press any key tocontinue . . .