Fortran的数组与指针

时间:2023-03-09 05:43:26
Fortran的数组与指针

个人理解,欢迎指正

指针就是记录数据的内存地址的变量。指针可以指向单个变量,也可以指向数组。

数组是一个概念,是若干个类型相同的元素的有序集合。在Fortran语言中,数组中存放的元素,可以是整数,实数,复数,甚至结构体(或称自定义数据类型)。但是,在Fortran中,数组中存放的元素不能是指针。不存在这样一个数组,该数组的每一个元素都是一个指针,分别指向不同的数组。

那么怎样才能实现,有一个数组,而数组中每一个元素都能指向其它数组呢?

因为数组中存放的元素可以是结构体,那么可以通过定义一个结构体,在结构体中定义一个指针变量来解决。

type container
class(object), pointer :: obj
end type container type(container), allocatable, dimension(:) :: objects
allocate (objects(:num_objects))
objects()%obj => s1

其中,objects(0:num_objects)就是定义的结构体数组,数组中的第0个元素的obj分量(objects(0)%obj)指向一个变量s1,s1是类型为object的变量。

上式objects数组中的每一个元素都是指向单个变量的,那么如果需要结构体数组中的每一个元素都指向一个数组,则定义结构体中的指针变量需要定义为是指向数组的(下面第10行):

 program ex1
implicit none
integer :: i,j !//声明目标数组work
real(RK),allocatable,target :: work(:,:) !//定义结构体类型qcontainer,该类型中的分量obj可以指向一个一维的数组
type qcontainer
real(RK),pointer :: obj(:)
end type qcontainer !//声明一个一维的的数组qtwork
type(qcontainer),allocatable :: qtwork(:) !//定义数组work并赋初值
allocate(work(,))
do i=,
do j=,
work(i,j)=i*j***
end do
end do !//定义数组qtwork
allocate(qtwork()) !//qtwork中第j个元素的object分量指向数组work的第j列
qtwork(j)%obj => work(:,j) end program ex1

关于彭书中的“”指针数组“

彭国伦《Fortran95程序设计》书中275页上说,“指针也可以声明成数组”,并给了以下示例代码

 program ex1004
implicit none
integer, pointer :: a(:)
integer, target :: b()=(/ ,,,, /)
! 把指针数组a指向数组b
a=>b
! a(~)=>b(~)
write(*,*) a
a=>b(:)
! a()=>b(), a()=>b(), a()=>b()
write(*,*) a
a=>b(::)
! a()=>b(), a()=>b(), a()=>b()
write(*,*) a
a=>b(::-)
! a()=>b(), a()=>b(), a()=>b(), a()=>b(), a()=>b()
write(*,*) a
stop
end

这里用指针a表示了数组b。这告诉我们,指针不仅可以指向单个变量的内存地址,还可以指向数组。

但是需要注意的是,指针a(:)中的每一个变量a(i)都确定的表示了某一个单独的变量,而不是表示变量的集合的数组即指针a(:)只能表示一个数组,不能同时表示多个数组的集合。

另外,需要注意,声明指针a的时候,可以说明a的形状,但不能指定a的数组大小。换句话说,声明指针a的时候,可以告诉编译器,a所指向的变量是几维的数组,但是不能告诉编译器,a所指向的数组是大小是100×100的。

第3行换成以下语句是非法的

!//非法的代码
integer, pointer :: a()

编译器错误提示是“ ALLOCATABLE or POINTER attribute dictates a deferred-shape-array.” 即声明变量时,allocatable或pointer的属性表明数组为假定形状数组。如果此时声明上述语句(即给了数组的大小),那显然矛盾。

总结

  • 在Fortran中,指针可以指向一个数组或者一个数组中的一部分,但指针不能同时表示多个数组。
  • 数组是若干相同类型元素的集合,但数组的元素不能是指针。
  • 如果想实现一个数组,且数组的元素具有指针的功能,可以定义一个结构体类型的数组。

附录代码:

 program test
implicit none
integer i,j,k
real,allocatable,target :: work(:,:) type qcontainer
real,pointer :: obj(:)
end type qcontainer type(qcontainer),allocatable :: qtwork(:) ,qtemp allocate(work(,))
allocate(qtwork()) !//初始化
do j=,
do i=,
work(i,j)=i*j***
end do
end do !//指针变量赋值
do j=,
qtwork(j)%obj => work(:,j)
end do !//打印输入数组
print*,"input array: "
do j=,
print*,work(:,j)
end do !//打印指向的数组
print*,"point array: "
do j=,
print*,qtwork(j)%obj
end do !//置换
print*,"swap"
qtemp = qtwork()
do j=,
qtwork(j) = qtwork(j+)
end do
qtwork()=qtemp !//输出置换结果
do j=,
print*,qtwork(j)%obj
end do deallocate(work) end program

输出结果:

 input array:
7.000000 14.00000
28.00000 56.00000
63.00000 126.0000
point array:
7.000000 14.00000
28.00000 56.00000
63.00000 126.0000
swap
28.00000 56.00000
63.00000 126.0000
7.000000 14.00000
Press any key to continue . . .

相关文章