2016-10-01 13 views
2

私は簡潔なタイトルに苦労していますが、それほど複雑ではありません。構造体(派生型)を返す関数があり、関数を呼び出すときに構造体の一部だけを参照する簡単な方法を探しています(別の構造体をコピー/ポインティングすることなく)。構造体/派生型を返す関数の参照

program main 

    real :: xx = 1. 
    real :: yy = 2. 

    ! works fine but what I want is to be 
    ! able to return %tx and %ts separately 

    print *, " tax ", tax(xx,yy) 

    ! just guessing at possible syntax here, but neither works 

    print *, " tax ", tax%tx(xx,yy) 
    print *, " tax ", tax(xx,yy)%tx 

contains 

function tax(x,y) 

    real :: x, y 

    type tTax 
     real :: tx, ty 
    end type tTax 

    type(tTax) :: tax 

    tax%tx = x * 100. 
    tax%ty = y * 100. 

end function tax 

end program main 

私はf90/f95機能セットに制限されていますが、f2003回答も含めてください。

私は本当にここに単純なものがあればそれを探しています。さもなければ、サブルーチンとして行うほうが良いでしょう(代わりにポインタを関数として保持していますが、ポインタやインタフェースなどを追加している場合)。

構造体の代わりに2次元配列を返しても同じ基本的な問題がありました。機能はありますが、配列セクション全体を印刷することはできません。

()が索引付け[]を使用してPythonのような言語とは対照的に、(FORTRANの関数や配列セクションの両方に使用するので、それは機能やインデックスなどを混在させるような何かかなり自然なことですされているので、私もそこに構文を推測トラブルがありましたtax(xx,yy)[1,:])。

答えて

3

派生データ型の名前を関数returnでオーバーロードすることによって、ユーザー定義のコンストラクタを作成できます。

Fortran 2003標準のassociate構造を自由に使用することで、メモリリークの起こりやすいポインタをコピーまたは頼らずに特定のタイプのコンポーネントにアクセスすることができます。

自分自身をFortran 2003に制限する特別な理由はありますか。最も人気のあるコンパイラではFortran 2008の多くがサポートされています。

次のコード

module mymod 

    ! Explicit typing only 
    implicit none 

    ! Declare derived data type 
    type tTax 
    real :: tx, ty 
    end type tTax 

    ! User-defined constructor 
    interface tTax 
    module procedure tax 
    end interface tTax 

contains 

    function tax(x, y) result (return_value) 
    real, intent (in) :: x, y 
    type (tTax)  :: return_value 

    return_value%tx = x * 100.0 
    return_value%ty = y * 100.0 

    end function tax 

end module mymod 

program main 

    use mymod 

    ! Explicit typing only 
    implicit none 

    real  :: xx = 1.0, yy = 2.0 
    type(tTax) :: foo 

    print *, " tax ", tax(xx,yy) 
    print *, " tax ", tTax(xx, yy) 

    ! Invoke the user-defined constructor 
    foo = tTax(xx, yy) 

    ! Fortran 2003's associate construct 
    associate(& 
     tx => foo%tx, & 
     ty => foo%ty & 
     ) 
     print *, " tax ", tx, ty 
    end associate 

end program main 

は、それはあなたが表現かどうかのコンポーネントまたは要素を参照することが許可されているだけかどうかで、

gfortran -Wall -o main.exe mymod.f90 main.f90 
./main.exe 
    tax 100.000000  200.000000  
    tax 100.000000  200.000000  
    tax 100.000000  200.000000 
+1

ありがとうございます。私が疑問に思ったように、fortranはこの余分な作業をして、実用的な観点からは少し単純なのでサブルーチンを使うかもしれません - そして、現時点ではそれをテストするのに十分な新しいコンパイラがありませんとにかく;-)しかし、これはクールです、ありがとう! – JohnE

+0

私はf2003なしで知っている私はメインで 'associate()'を使用することはできませんが、モジュール自体は私のためにコンパイルする必要がありますか?私のf90コンパイラは、タイプとインターフェイスの両方についてtTaxの名前を使用して文句を言いますが、別々にコンパイルします(もちろんメインはこれらのケースでは機能しません)。私がtxではなくmainでfoo%txを使うことができれば、私のperspeciveから十分な解決策になるでしょう。 – JohnE

+0

@VladimirFまたはjlok:ここのコメントに簡単に答えがありますか?それとも別の質問として聞く価値があるのですか? – JohnE

3

問題は括弧記号ではありませんが得られます。

Fortranでは、許可されていません。 %構文または配列indexing()は、変数名または定数名または関連名に対してのみ使用できます。

+0

それは私の仕事の前提でしたが、私は常にfortranのエモスに反するようなpython-esque構文的砂糖アルトを期待しています。 ;-) – JohnE

+0

@ JohnEここにPython Fortran Rosetta Stone http:// wwwへのリンクがあります。fortran90.org/src/rosetta.html – jlokimlin

+0

@jlokimlinええ、興味深いことに私の問題のために面白いのですが、fortran **サブルーチン**をpython/numpyと同等のものとして扱います!私の問題は明らかに、私はPython関数のようにFortran関数を動作させようとしており、私はFortranをPythonのように見せかけるように努力しているかもしれません。 – JohnE

関連する問題