nAG Fortran コンパイラ 7.2 マニュアル

 
ナビゲーション:前へ   上へ   次へ

10.3 データ実体の宣言 [大部分 6.0]

  • 配列の最大次元数が7から15に変更されました。 例えば
       REAL array(2,2,2,2,2,2,2,2,2,2,2,2,2,2,2)
    
    は15次元の配列を宣言します。
  • [3.0] 64ビット整数サポートが必須です。SELECTED_INT_KIND(18)の結果は有効な整数種別番号です。
  • 配列の名前付き定数(PARAMETER)の形状を定義式より引き継ぐことができます。(推定形状配列) 書式は配列のすべての次元の上限をアスタリスクで指定します。 例えば
       REAL,PARAMETER :: idmat3(*,*) = Reshape( [ 1,0,0,0,1,0,0,0,1 ], [ 3,3 ] )
       REAL,PARAMETER :: yeardata(2000:*) = [ 1,2,3,4,5,6,7,8,9 ]
    
    ではidmat3の上下限が(1:3,1:3)でありyeardataの上下限が(2000:2008)です。
  • 組込みの型指定を括弧内に含めることにより簡単に TYPE キーワードを用いた組込型を宣言することが可能です。 例えば
       TYPE(REAL) x
       TYPE(COMPLEX(KIND(0d0))) y
       TYPE(CHARACTER(LEN=80)) z
    
    は(よりわかりにくい点を除き)以下と同等です。
       REAL x
       COMPLEX(KIND(0d0)) y
       CHARACTER(LEN=80) z
    
  • この拡張によりDOUBLEPRECISIONという名前の拡張型を定義することが許されなくなりました。
  • [5.3] 型束縛手続宣言文が複数の型束縛手続を宣言できるようになりました。
    例)
          PROCEDURE,NOPASS :: a
          PROCEDURE,NOPASS :: b=>x
          PROCEDURE,NOPASS :: c
    
    は以下のように書くことができます。
          PROCEDURE,NOPASS :: a, b=>x, c
    
  • [5.3 C_ASSOCIATED、7.0 C_LOC及びC_FUNLOC] 宣言式でISO_C_BINDINGモジュールのC_ASSOCIATEDC_LOC、及びC_FUNLOC関数が使用できるようになりました。 たとえば、TYPE(C_PTR)の変数Xと、TARGET属性を持つ別の相互運用可能な変数Yが与えられた場合、
           INTEGER workspace(MERGE(10,20,C_ASSOCIATED(X,C_LOC(Y))))
    
    と記述できるようになり、CポインターXYに関連付けられている場合はworkspaceが10要素分の大きさとなり、それ以外の場合は20要素分の大きさとなります。
  • [7.0] 演算が宣言関数によって与えられる場合、宣言式でユーザー定義の演算が行えるようになりました。 (宣言関数は仮手続き引数を持たない、文関数以外の純粋な関数、もしくは内部関数でなければなりません。) 例えば以下の引用仕様宣言で
           INTERFACE OPERATOR(.user.)
              PURE INTEGER FUNCTION userfun(x)
                 REAL,INTENT(IN) :: x
              END FUNCTION
           END INTERFACE
    
    ユーザー定義演算子.user.は、次のように宣言式で使用できます。
           LOGICAL mask(.user.(3.145))
    

    これはオーバーロードされた組込み演算子とユーザー定義演算子に適用されることに注意してください。

  • [7.1] 割付け可能な成分は、型を前方参照できます。次に例を示します。
           Type t2
             Type(t),Pointer :: p
             Type(t),Allocatable :: a
           End Type
           Type t
             Integer c
           End Type
    

    割付け可能な成分は再帰型にすることも、2つの型を相互に再帰的にすることもできます。
    例)

           Type t
             Integer v
             Type(t),Allocatable :: a
           End Type
    
    これにより、割付け可能な成分を使用してリストとツリーを構築できます。 このようなデータ構造を構築または走査するには、通常再帰的な手続き呼び出しが必要になります。(ポインタ代入に類似したものがないため)

    このような再帰的なデータ構造がどれほど深くネストされていても、循環することはできません。(これも、ポインター代入がないため) 通常どおり、そのような構造の最上位オブジェクトの割付けを解除すると、割付け可能なすべての成分の割付けが再帰的に解除されます。

  • [7.1] 仮引数は、関数結果の型パラメタ(文字長など)を指定するために使用されない限り、成分副プログラムの宣言式で使用できます。 関数結果の型パラメタの場合、照会が据え置き特性に関するものでない場合、宣言問合せ(LENなど)の場合のように制限されたままになります。

    例)

      Elemental Subroutine s(x,n,y)
        Real,Intent(In) :: x
        Integer,Intent(In) :: n
        Real,Intent(Out) :: y
        Real temp(n)
        ...
    
    仮引数Nを使用して、ローカル配列TEMPを宣言できます。
  • [7.1] ポインタとポインタ成分は、指示先を指すように初期化できます。 指示先はそのポインタに対して有効である必要があります。(同じ型、次元数など) 主に以下のような場合があります。
    名前付き初期値指定
    データポインタの場合、指示先にはSAVE属性が必要です(モジュール内の変数と主プログラムには暗黙的にこの属性があります)。 手続きポインタの場合、指示先は、仮手続き、内部手続き、または文関数ではなく、モジュール手続きまたは外部手続きである必要があります。

    例)

      Module m
        Real,Target :: x
        Real,Pointer :: p => x
      End Module
      Program test
        Use m
        p = 3
        Print *,x ! Will print the value 3.0
      End Program
    
    成分の暗黙的初期値指定
    ポインタ成分は、指示先を指すように暗黙的初期値指定ができます。 指示先の要件は、名前付きポインターの初期値指定の場合と同じです。

    例)

      Module m
        Real,Target :: x
        Type t
          Real,Pointer :: p => x
        End Type
      End Module
      Program test
        Use m
        Type(t) y
        y%p = 3
        Print *,x ! Will print the value 3.0
      End Program
    
    構造体構成子による成分初期値指定
    定数式の構造体構成子は任意のポインター成分の指示先を指定できます。 指示先の要件は、名前付きポインターの初期値指定の場合と同じです。

    例)

      Module m
        Real,Target :: x
        Type t
          Real,Pointer :: p
        End Type
      End Module
      Program test
        Use m
        Type(t) :: y = t(x)
        y%p = 3
        Print *,x ! Will print the value 3.0
      End Program
    
  • [7.1] ポインタを返す関数への参照は、多くのコンテキストで変数として使用できます。 具体的には、代入文の変数としてINTENT(OUT)またはINTENT(INOUT)仮引数に対応する実引数として、 および選択子及び結合名を変更するASSOCIATEまたはSELECT TYPE構文で使用できます。

    例)

      Module m
        Real,Target,Save :: table(100) = 0
      Contains
        Function f(n)
          Integer,Intent(In) :: n
          Real,Pointer :: f
          f => table(Min(Max(1,n),Size(table)))
        End Function
      End Module
    
    上記モジュールを利用する以下のプログラムは“-1.23E+02”を出力します。
      Program example
        Use m
        f(13) = -123
        Print 1,f(13)
      1 Format(ES10.3)
      End Program
    

    文関数定義の構文は、変数としてのポインター関数参照の構文の一部と同じであることに注意してください。 有効範囲内でアクセス可能なポインター値関数の存在によって、これらの関数がどれであるかが決まります。 そのため、状況によっては混乱を招くエラーメッセージが表示される場合があります。

    上述のモジュールを利用するASSOCIATE構文の例を以下に示します。

      Program assoc_eg
        Use m
        Associate(x=>f(3), y=>f(4))
          x = 0.5
          y = 3/x
        End Associate
        Print 1,table(3:4) ! Will print "  5.00E-01  6.00E+00"
      1 Format(2ES10.2)
      End Program
    

    最後に、引数の受け渡しの例を以下に示します。

      Program argument_eg
        Use m
        Call set(f(7))
        Print 1,table(7) ! Will print "1.41421"
      1 Format(F7.5)
      Contains
        Subroutine set(x)
          Real,Intent(Out) :: x
          x = Sqrt(2.0)
        End Subroutine
      End Program
    

    変数指定子の代わりにポインター値関数への参照を使用できるその他のコンテキストには、次のものがあります。

    • WRITE文の内部ファイル指定子として(関数は、このために文字列または配列へのポインターを返す必要があります)。
    • READ文の入力項目として
    • ALLOCATEまたはDEALLOCATE文、またはEVENT WAITなどの像制御文のSTAT=またはERRMSG=変数として
    • FORM TEAM文のチーム変数として
  • [7.1] 関数の結果が手続きポインタである場合があります。
    例)
      Module ppfun
        Private
        Abstract Interface
          Subroutine charsub(string)
            Character(*),Intent(In) :: string
          End Subroutine
        End Interface
        Public charsub,hello_goodbye
      Contains
        Subroutine hello(string)
          Character(*),Intent(In) :: string
          Print *,'Hello: ',string
        End Subroutine
        Subroutine bye(string)
          Character(*),Intent(In) :: string
          Print *,'Goodbye: ',string
          Stop
        End Subroutine
        Function hello_goodbye(flag)
          Logical,Intent(In) :: flag
          Procedure(hello),Pointer :: hello_goodbye
          If (flag) Then
            hello_goodbye => hello
          Else
            hello_goodbye => bye
          End If
        End Function
      End Module
      Program example
        Use ppfun
        Procedure(charsub),Pointer :: pp
        pp => hello_goodbye(.True.)
        Call pp('One')
        pp => hello_goodbye(.False.)
        Call pp('Two')
      End Program
    
    The function hello_goodbye in module ppfun returns a pointer to a procedure, which needs to be pointer-assigned to a procedure pointer to be invoked. When executed, this example will print モジュールppfunの関数hello_goodbyeは、手続きへのポインタを返します。 このポインタは、呼び出される手続きポインタにポインタ代入される必要があります。 実行すると、以下が出力されます。
     Hello: One
     Goodbye: Two
    

    この機能の使用は、データ実体と手続きの間の境界線を曖昧にするため、お勧めしません。 (コードのメンテナンス中に混乱や誤解を招く可能性があります。) この機能は、手続きポインタ成分によって提供されている以外は提供しません。

© 日本ニューメリカルアルゴリズムズグループ株式会社 2025
Privacy Policy  /  Trademarks