将派生类型中的指针分配给 Fortran 中相同类型中的目标

Chi*_*iel 3 fortran

我想在包含在同一派生类型中的派生类型中分配一个指针。下面的代码给了我下面的错误。这是怎么回事,我该如何解决这个问题?

   24 |         zoos(i)%tigers(1) => zoos(i)%animals(1, 1)
      |        1
Error: Expected bounds specification for 'zoos' at (1)
Run Code Online (Sandbox Code Playgroud)
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(1) => zoos(i)%animals(1, 1)
        zoos(i)%ducks(1) => zoos(i)%animals(1, 2)
    end do
end program test
Run Code Online (Sandbox Code Playgroud)

ver*_*rie 5

该问题与派生类型无关,并且错误消息是错误的。

问题是zoos(i)%ducks是指向数组的指针,而不是指针数组,因此您需要指向zoos(i)%ducksat zoos(i)%animals(:, 2),而不是zoos(i)%ducks(1)at 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
Run Code Online (Sandbox Code Playgroud)

我还想提出一个框架挑战。正如评论中(尤其是 Ian Bush)所指出的,Fortran 中的指针非常容易出错。

我建议将任何分配的pointers 替换为allocatables。如果有s 指向它们,这些allocatables 也必须是s,如下所示:targetpointer

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
Run Code Online (Sandbox Code Playgroud)

尽可能使用allocatables 比s有许多优点:pointer

  • 当 s脱离范围1时,s所持有的内存allocatable将自动释放。allocatable
  • allocatable编译器可以对s 做出比s更强的假设pointer,有时会产生更快的代码。

1至少,根据 Fortran 标准,这是正确的。一些编译器存在几个与终结相关的突出问题(特别是这个错误)。

  • (FWIW,没有声称答案,但我对可分配组件感到有点过度担心(?)...)如果可能,将结果与至少两个编译器(ifort 和 gfort)进行比较可能是有用的建议(虽然我总是忘记这样做...XD) (2认同)