我已经编写一个用于热力学计算的大型 Fortran 程序近 10 年了,当我开始时,我对新的 Fortran 标准还很陌生(我很熟悉 F77,而且太老了,无法学习其他东西)。我发现新的 TYPE 构造非常好并且经常使用它们,但我没有意识到一些限制,例如不允许创建指针数组,我后来发现了这一点。
现在我正在纠正一些旧代码,我惊讶地发现在记录声明中: TYPE gtp_phase_add
声明:TYPE(tpfun_expression)、dimension(:)、指针 :: explink
其中 explink 用于指向另一个包含数学表达式的结构。这并没有产生任何编译错误(我通常使用 gfortran,但我也使用 intel fortran 编译了这个程序)。当我看到这段旧代码(大约 10 年前写的)时,我以为缺少一个“可分配”,但添加后却出现了编译错误。
我制作了一个最小的完整程序来模仿它的使用方式:
MODULE test1
implicit none
TYPE tpfun_expression
integer nc
double precision, allocatable, dimension(:) :: coeffs
integer, allocatable, dimension(:) :: powers
END type tpfun_expression
TYPE gtp_phase_add
!**************************************************************************
! My question is if it is correct Fortran to have an array of pointers here
TYPE(tpfun_expression), dimension(:), pointer :: explink
!**************************************************************************
TYPE(gtp_phase_add), pointer :: nextadd
END TYPE gtp_phase_add
contains
subroutine create_tpfun(n,coeffs,powers,exp)
integer n,i,powers(*)
double precision coeffs(*)
type(tpfun_expression), pointer :: exp
allocate(exp%coeffs(n))
allocate(exp%powers(n))
exp%nc=n
do i=1,n
exp%coeffs(i)=coeffs(i)
exp%powers(i)=powers(i)
enddo
return
end subroutine create_tpfun
subroutine create_addrec(typ,this)
integer typ,n,m
TYPE(tpfun_expression), target :: exp1
TYPE(tpfun_expression), pointer :: exp2
TYPE(gtp_phase_add), pointer :: this
integer ipow(4)
double precision coeffs(4)
!
!**************************************************************************
! here I allocate a pointer array
allocate(this%explink(typ))
!**************************************************************************
if(typ.eq.1) then
do m=1,4
ipow(m)=m-1
coeffs(m)=2.0D0*m
enddo
exp2=>this%explink(1)
call create_tpfun(4,coeffs,ipow,exp2)
else
do m=1,4
ipow(m)=m-1
coeffs(m)=3.0D0
enddo
exp2=>this%explink(1)
call create_tpfun(4,coeffs,ipow,exp2)
do m=1,3
ipow(m)=1-m
coeffs(m)=5.0D0
enddo
exp2=>this%explink(2)
call create_tpfun(3,coeffs,ipow,exp2)
endif
return
end subroutine create_addrec
end MODULE test1
program main
use test1
integer n,m,j,k,q
TYPE(gtp_phase_add), target :: addrec
TYPE(gtp_phase_add), pointer :: next,first
TYPE(tpfun_expression) :: exp
first=>addrec
next=>addrec
write(*,*)'Creating addrec 1'
call create_addrec(1,next)
allocate(next%nextadd)
write(*,*)'Creating addrec 2'
next=>next%nextadd
call create_addrec(2,next)
! just a check that the functions are correct
write(*,*)'Listing functions in all addrecs'
next=>first
q=0
do while(associated(next))
q=q+1
write(*,*)'Addition record ',q
n=size(next%explink)
do m=1,n
k=next%explink(m)%nc
write(*,10)(next%explink(m)%coeffs(j),next%explink(m)%powers(j),j=1,k)
enddo
10 format(10(F6.3,1x,i3))
next=>next%nextadd
enddo
end program main
这正如我所期望的那样,我只是惊讶于我允许声明一个指针数组,所以我想知道这是否是正确的 Fortran。
如果我无法理解如何更优雅地编辑它,我很抱歉。