ナビゲーション:前へ 上へ 次へ
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.0C_LOC
及びC_FUNLOC
] 宣言式でISO_C_BINDING
モジュールのC_ASSOCIATED
、C_LOC
、及びC_FUNLOC
関数が使用できるようになりました。 たとえば、TYPE(C_PTR)
の変数Xと、TARGET
属性を持つ別の相互運用可能な変数Y
が与えられた場合、INTEGER workspace(MERGE(10,20,C_ASSOCIATED(X,C_LOC(Y))))
と記述できるようになり、CポインターX
がY
に関連付けられている場合は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 functionhello_goodbye
in moduleppfun
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
この機能の使用は、データ実体と手続きの間の境界線を曖昧にするため、お勧めしません。 (コードのメンテナンス中に混乱や誤解を招く可能性があります。) この機能は、手続きポインタ成分によって提供されている以外は提供しません。