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 でコンパイルできますが、実行するとセグメンテーション エラーが発生しました。

再帰的な割り当て可能な型を割り当てる方法はありますか?

4

2 に答える 2

4

コードの表面的な問題は、式p%p_dx%init_dx(2)が計算されるときにポインター コンポーネントp%p_dxが定義されておらず、セグメンテーション違反が発生することです。ポインタは未定義であり、関連付けられていないだけではないことに注意してください。

現在、私は迅速な修正を考え出すのに苦労しています。長い修正は、あなたのアプローチの重大な欠陥であると私が考えるものに対処することです。これは白か黒かの問題ではなく、私の意見であることに注意してください。

関数initinit_dxには副作用がないわけではありません。実際、ほとんどすべてが副作用であると言えます。それらは論理値を返し、副作用としてpolynom変数を初期化します。プログラムには、評価せpolynomずに a を初期化する方法がなく、次のようなステートメントにラップせずinitに評価する方法がないようです。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)
于 2013-05-07T13:24:29.620 に答える
1

私自身の質問に答えて、ポインターなしでも機能する別のソリューションを思いつきましたが、マークのものほどエレガントではありません。

他のタイプを定義します:

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)
于 2013-05-08T10:54:26.163 に答える