2016-08-12 3 views
0

私は、このような モジュール

module test 

use othermod, only: n 

integer, dimension(n) :: var0 
real, dimension(n) :: var1 
real, dimension(n) :: var2 
..... 
real, dimension(n) :: var1000 

end module test 

としてモジュールで宣言された変数の数を持っている中で、すべての変数から配列の配列を作成する方法それから私は、値でこれらの変数を満たすサブルーチンを持っています。 この時点で、私はモジュールtestで宣言されたすべての変数を持つ配列の配列を作成したいので、dimension(n、allvariablesin module test)のように特定の(n)のすべての変数を同時に簡単にコピーまたは印刷することができます)。例えば、私はarray(3、:)= array(2、:)のようなことをしたいと思います。 このコードは非常に大きなプログラムの一部ですので、あまり変更することはできませんが、すべての変数を入力せずにこのモジュールのすべての変数から配列の配列を作成する必要があります。 この変更を現在のコードに簡単に統合するにはどうすればよいですか?

+1

次のコードでのJavaスタイルのコンストラクタを取得するタイプの名前をオーバーロードすることができます。または、そこにポインタを格納します。 Fortranに配列の配列はありません。 –

+0

私は@VladimirFに同意します。モジュール内のすべての変数宣言は自動的に 'save'属性を継承しています。 'var0、var1、var2、...、var1000'配列の異なるインスタンスが' n'の異なる値になるようにするには、型のコンポーネントとして変数を派生データ型で囲む必要があります。 – jlokimlin

+0

配列の構造がありますが、なぜですか?ルーチンと関数でUSE TESTを使用すると、そこにすべてが表示されます。 array(3、:)= array(2、:)は、var1(:) = var2(:)よりもはるかに時間を節約できます。 var1がMassでvar2が重みである場合、massweight(1、:)は質量、massweight(2、:)は重みです。 var1がX軸、Var2がY軸の場合、xy(:, :)は2次元配列として意味があります。そうでなければ配列として保持する方が意味がありますか? – Holmz

答えて

1

@Vladimir Fのアドバイスに従い、派生型の中に変数をカプセル化することをお勧めします。あなたはvar0, var1, ..,など最後を期待して、古いコードを呼び出すためのassociate構造を採用することができ、我々は派生型を作成し、そこにそれらを格納

module type_MyArray 

    implicit none 
    private 

    type, public :: MyArray 
    ! type-components 
    real, dimension(:), allocatable :: var0, var1, var2 
    contains 
    ! type-bound procedures 
    procedure :: create => create_my_array 
    procedure :: destroy => destroy_my_array 
    end type MyArray 

    interface MyArray 
    module procedure my_array_constructor 
    end interface MyArray 

contains 

    pure function my_array_constructor(n) result (return_value) 
    ! Dummy arguments 
    integer, intent (in) :: n 
    type (MyArray)  :: return_value 

    call return_value%create(n) 

    end function my_array_constructor 


    pure subroutine create_my_array(self, n) 
    ! Dummy arguments 
    class(MyArray), intent(in out) :: self 
    integer,  intent(in)  :: n 

    allocate(self%var0(n)) 
    allocate(self%var1(n)) 
    allocate(self%var2(n)) 

    end subroutine create_my_array 


    pure subroutine destroy_my_array(self) 
    ! Dummy arguments 
    class(MyArray), intent(in out) :: self 

    if (allocated(self%var0)) deallocate(self%var0) 
    if (allocated(self%var1)) deallocate(self%var1) 
    if (allocated(self%var2)) deallocate(self%var2) 

    end subroutine destroy_my_array 

end module type_MyArray 

program main 

    use type_MyArray, only: MyArray 
    use old_code,  only: do_something 

    implicit none 

    type (MyArray) :: foo, bar 

    ! Allocate memory 
    foo = MyArray(42) 
    bar = MyArray(4200) 

    associate(var0 => foo%var0, var1 => bar%var1) 

    ! Call old code using var0 and var1 
    call do_something(var0, var1) 

    end associate 

    ! Release memory 
    call foo%destroy() 
    call bar%destroy() 

end program main 
+0

このソリューションをお寄せいただきありがとうございます。私はFortranに精通していないので、このすべての仕組みを理解する必要があります。私が言いたいことは、古い変数を代用する必要はなく、残っている変数はそのまま残しておくということです。この新しいタイプはコードにのみ追加されます。したがって、データ型では、整数、実数、論理を一緒に持つことができますか? –

+0

私は、オブジェクト指向のソフトウェア設計と優れたFortranのプラクティスをブラッシュアップすることをお勧めします。 http://www.fortran90.org/の便利なリンクが見つかるかもしれません。 – jlokimlin

関連する問題