将派生类型中的指针分配给Fortran中相同类型的目标
我想在同一派生类型中包含的派生类型中指定一个指针。下面的代码给出了下面的错误。这是怎么回事,我该怎么解决将派生类型中的指针分配给Fortran中相同类型的目标,fortran,Fortran,我想在同一派生类型中包含的派生类型中指定一个指针。下面的代码给出了下面的错误。这是怎么回事,我该怎么解决 24 | zoos(i)%tigers(1) => zoos(i)%animals(1, 1) | 1 Error: Expected bounds specification for 'zoos' at (1) 问题与派生类型无关,错误消息是错误的 问题是zoos(i)%ducks是指向数组的指针,而不是指针数组,因此您需要将zoos
24 | zoos(i)%tigers(1) => zoos(i)%animals(1, 1)
| 1
Error: Expected bounds specification for 'zoos' at (1)
问题与派生类型无关,错误消息是错误的 问题是
zoos(i)%ducks
是指向数组的指针,而不是指针数组,因此您需要将zoos(i)%ducks
指向zoos(i)%animals(:,2)
,而不是zoos(i)%ducks(1)
指向zoos(i)%animals(1,2)
我之前已经谈到过这一点
我相信这正是你想要的:
module mo_zoo
implicit none
type zoo
integer, dimension(:,:), pointer :: animals
integer, dimension(:), pointer :: tigers
integer, dimension(:), pointer :: ducks
end type zoo
save
type(zoo), dimension(:), pointer :: zoos
end module mo_zoo
program test
use mo_zoo
implicit none
integer :: n_zoos
integer :: i
n_zoos = 4
allocate(zoos(n_zoos))
do i = 1, n_zoos
allocate(zoos(i)%animals(10, 2))
zoos(i)%tigers => zoos(i)%animals(:, 1)
zoos(i)%ducks => zoos(i)%animals(:, 2)
end do
end program test
我还想提出一个框架挑战。正如Ian Bush在评论中特别指出的那样,Fortran中的指针是出了名的容易出错的
我建议将任何已分配的指针
s替换为可分配的
s。这些可分配的
s也需要是目标
s,如果它们有指针
s指向它们,如下所示:
module mo_zoo
implicit none
type zoo
integer, dimension(:,:), allocatable :: animals
integer, dimension(:), pointer :: tigers
integer, dimension(:), pointer :: ducks
end type zoo
save
type(zoo), dimension(:), allocatable, target :: zoos
end module mo_zoo
program test
use mo_zoo
implicit none
integer :: n_zoos
integer :: i
n_zoos = 4
allocate(zoos(n_zoos))
do i = 1, n_zoos
allocate(zoos(i)%animals(10, 2))
zoos(i)%tigers => zoos(i)%animals(:, 1)
zoos(i)%ducks => zoos(i)%animals(:, 2)
end do
end program test
在可能的情况下,使用可分配
s优于指针
s有许多优点:
s持有的内存将在allocatable
s退出作用域1时自动释放allocatable
- 编译器可以对
s做出比可分配
s更强的假设,有时会导致更快的代码指针
1至少,根据Fortran标准,这是正确的。一些编译器(尤其是)在最终定稿方面存在一些突出的问题。可能是重复的吗?我认为我的情况更复杂,因为指针包含在派生类型的数组中。可分配性几乎总是优越的——当然,这里所示的二维数组没有理由不可分配,可能目标属性取决于您所做的其他事情,但我很难理解数组的维度。为什么动物是二维数组,而老虎和鸭子是一维数组?当你做指针赋值时,你只指向一个元素,那么为什么是一维数组呢?我想指向数组中的一个范围。对不起,我的Fortran已经生锈了,这是我很长一段时间以来的第一次编码。这确实奏效了。我原以为指向第一个元素就行了,但我显然考虑了更多的C风格。我仍然会在适当的时候使用allocatables…@veryreverie我也一直在使用Gfortran作为我的主编译器(谢谢!!),我的经验是,
allocatable
派生类型中的数组现在非常成熟/稳定,我最近基本上没有遇到任何问题(例如,即使是嵌套可分配对象的“深度复制”)。但我仍然避免使用(1)final
例程(以及对象的意图(out)),和(2)多态分配+LHS的自动分配(相反,我使用源分配,如allocate(objA,source=objB)
)。考虑到这两个注意事项,我认为allocatable
可以使用(或推荐),特别是当gfort>=10:)(FWIW,没有声明答案,但我觉得有点过于担心(?)可分配组件…),如果可能的话,将结果与至少两个编译器(ifort和gfort)进行比较可能是一个有用的建议(尽管我总是忘记这么做…XD),我在gfortran中广泛使用inten(out)和多态分配+LHS的自动分配,并且最近没有出现任何问题(gfortran 7+)。不过我不太使用定稿功能——这是一个让我感兴趣的功能,但在考试中却不太适合我的需要。
module mo_zoo
implicit none
type zoo
integer, dimension(:,:), allocatable :: animals
integer, dimension(:), pointer :: tigers
integer, dimension(:), pointer :: ducks
end type zoo
save
type(zoo), dimension(:), allocatable, target :: zoos
end module mo_zoo
program test
use mo_zoo
implicit none
integer :: n_zoos
integer :: i
n_zoos = 4
allocate(zoos(n_zoos))
do i = 1, n_zoos
allocate(zoos(i)%animals(10, 2))
zoos(i)%tigers => zoos(i)%animals(:, 1)
zoos(i)%ducks => zoos(i)%animals(:, 2)
end do
end program test