首页 文章

可分配的用户派生类型

提问于
浏览
1

我有一个关于Fortran的问题和正确分配可分配用户派生类型 .

这是我的代码:

module polynom_mod
 implicit none

 type monomial
  integer,dimension(2) :: exponent
 end type

type polynom
  real, allocatable, dimension(:) :: coeff
  type(monomial),allocatable, dimension(:)   :: monom
  logical :: allocated
 !recursive type
  type(polynom),pointer :: p_dx,p_dy
 contains
  procedure :: init
  procedure :: init_dx
end type

在这里我想得到一个类型多项式,我可以做以下事情:

p%coeff(1)=1.0 
p%monom(1)%exponent(1)=2

和类似的东西:

p%p_dx%coeff(1)=1.0 
p%p_dx%monom(1)%exponent(1)=2

所以我写了一些init类型绑定程序,我可以初始化我的并分配我的类型:

contains

function init(this,num) result(stat)
  implicit none
  integer, intent(in)      :: num
  class(polynom),intent(inout) :: this
  logical :: stat

  allocate(this%coeff(num))
  allocate(this%monom(num))

  this%allocated = .TRUE.
  stat = .TRUE.
end function

function init_dx(this,num) result(stat)
  implicit none

  integer, intent(in)      :: num
  class(polynom),intent(inout) :: this

  logical :: stat

  allocate(this%p_dx%coeff(num))
  allocate(this%p_dx%monom(num))

  this%p_dx%allocated = .TRUE.
  stat = .TRUE.
 end function   
end module

program testpolytype
 use polynom_mod

 type(polynom) :: p

 if(p%init(2)) then
  print *,"Polynom allocated!"
 end if

 if(p%p_dx%init_dx(2)) then
  print *,"Polynom_dx allocated!"
 end if

结束计划

这将使用gfortran 4.6.3进行编译,但是当我运行它时,我遇到了分段错误!

有没有办法分配递归可分配类型?

2 回答

  • 0

    您的代码的表面问题是,当计算表达式 p%p_dx%init_dx(2) 时,指针组件 p%p_dx 未定义,并且引发了分段错误 . 请注意,指针未定义,并且不仅仅是关联 .

    现在我正在努力想出一个快速解决方案 . 长期的解决方案是解决我认为你的方法中的严重缺陷;请注意,这是我的意见,而不是黑色或白色的问题所以只有在你关心我的输入时才能阅读 .

    函数 initinit_dx 并没有副作用,实际上它们可以说几乎都是副作用 - 它们返回逻辑值,并且作为副作用,初始化 polynom 变量 . 该程序似乎无法在不评估 init 的情况下初始化 polynom 并且没有办法评估 init 而不将其包装到诸如

    if (p%init(2)) then
    end if
    

    我想,您可以将这些初始化函数重写为子例程,也许可以使用诸如的签名

    call initialise_polynom(p,2)
    

    这至少会从代码中删除不纯函数的污点 . 但更好的方法是编写一个函数,例如:

    function new_poly(num)
      implicit none
      integer, intent(in) :: num
      type(polynom) :: new_poly
      allocate(new_poly%coeff(num))
      allocate(new_poly%monom(num))
      allocate(new_poly%p_dx)
    end function new_poly
    

    哪一个

    a)返回一个新的 polynom ;和

    b)分配组件 p_dx ;和

    c)无副作用 .

    然后,您可以使用表达式创建一个新的 polynom

    p = new_poly(3)
    

    并使用诸如的表达式初始化组件

    p%p_dx = new_poly(3)
    
  • 2

    回答我自己的问题,我提出了另一个解决方案,女巫也没有指针,但它不像Marks那样优雅 .

    定义其他类型:

    type p_dx
     real, allocatable, dimension(:) :: coeff
     type(monomial),allocatable, dimension(:)   :: monom
     logical :: allocated
    end type
    

    然后使用它:

    type polynom
     real, allocatable, dimension(:) :: coeff
     type(monomial),allocatable, dimension(:)   :: monom
     type(p_dx) :: dx
     logical :: allocated
    contains
     procedure     :: init
    end type
    

    所以你可以这样做:

    type(polynom) :: p
    
    p%init(2)
    p%dx%init_dx(3)
    

相关问题