FORTRAN 77 言語リファレンス |
第 2 章
データ型とデータ項目
この章では、Sun FORTRAN 77 のデータ型とデータ構造について説明します。
規格外の機能には、普通小さな塗り潰した菱形 (©) が付きます。
データの型
通常、定数、定数式、変数、配列、配列要素、部分列、および関数は、 型を持つデータを表しています (型のない定数は例外です)。
一方、プログラムまたはサブルーチン、初期値設定副プログラム、共通ブロック、変数群、構造化記録は、データ型をもっていません。
データの型に関する規則
名前により型が決定されます。つまりデータや関数の名前により、以下のデータ型規則に従って、明示的または暗黙的にデータの型が決まります。
- 定数、変数、配列、および関数の英字名が持つデータの型は、総称関数以外は、1 つのプログラム単位について 1 つだけです。
- 型宣言文で明示的に名前の型を宣言するとデータの型が決まります。
- 型宣言文で明示的に名前の型を宣言しないと、名前の最初のアルファベットがデータの型を暗黙的に決めます。
- デフォルトの暗黙の型宣言規則では、名前の最初のアルファベットが
I、J、K、L、M、N
のいずれかであればそのデータ型は整数であり、それ以外の文字であれば実数です。IMPLICIT
文を使用して、デフォルトの暗黙の型宣言を変更できます。IMPLICIT NONE
文を使用して、暗黙の型宣言をすべて無効にすることもできます。コマンド行にコンパイラフラグ-u
を指定して、暗黙の型宣言をすべて無効にすることもできます。この方法は、各プログラム単位をIMPLICIT NONE
文で始める方法と結果が同じです。配列要素
関数
組み込み関数は、あらかじめ指定された型を持っています。組み込み関数には、明示的な型宣言文は必要ありませんが、型宣言をすることもできます。総称関数には、前もって決められた型はなく、「組み込み関数」で説明しているように、引数の型で決まります。
FUNCTION F ( X )INTEGER F, XF = X + 1RETURNEND
INTEGER FUNCTION F ( X )INTEGER XF = X + 1RETURNEND
FUNCTION NXT ( X )INTEGER XNXT = X + 1RETURNEND暗黙の型宣言は関数の型にも有効です。デフォルトでの暗黙の型宣言または
IMPLICIT
文によって関数の型を決めます。関数の副プログラムとそれを呼び出すプログラム単位とで関数の型を同じにするのは、ユーザーの責任です。つまり、f77
コンパイラ はプログラム単位間の型の一致を調べません。データの型の性質
本節では、Sun FORTRAN 77 のデータ型について説明しています。
データサイズを明示的に宣言しないデフォルトのデータ宣言は、特定のコンパイラオプションによって、その意味が変わってくる場合があります。「データ型のサイズと整列条件」の節では、データのサイズと整列条件とこれらのオプションの作用について説明します。
BYTE
©データの型
BYTE
は、記憶領域を 1 バイトだけ使用する型です。これは論理型で、LOGICAL
*1
と同義です。
BYTE
型の変数は以下の値のいずれかをとることができます。論理値と解釈された場合、0 は
.FALSE.
を表し、その他の値はすべて.TRUE.
です。
f77
では、配列の索引として (REAL
型と同様に)BYTE
型を使用できますが、DO
ループの索引としては使用できません (INTEGER、REAL、DOUBLE PRECISION
だけが使用できます)。コンパイラがINTEGER
の明示的チェックを必要とする場合、BYTE
は使用できません。
BYTE Bit3 / 8 /, C1 / 'W' /,& Counter / 0 /, Switch / .FALSE. /
BYTE
項目は 1 バイト (8 ビット) の記憶領域を占め、 1 バイトの境界を割り当てられます。
CHARACTER
文字データ型
CHARACTER
は、CHARACTER*1
と同義で 1 文字のデータを表現します。文字はアポストロフィ (') または引用符 (") で囲みます。© 引用符 (") は規格外であり、
-xl
オプションを指定してコンパイルする場合は、引用符は別の意味になるので、文字列を囲むにはアポストロフィを使用しなければなりません。
CHARACTER
型のデータには符号が付きません。CHARACTER
項目は 1 バイト (8 ビット) の記憶領域を占め、1 バイト境界に割り当てられます。
CHARACTER *n
文字列データ型
CHARACTER
*n (n>
0
) は n 個の文字の列を表現します。
CHARACTER
*n のデータ型は n バイトの記憶領域を占め、1 バイトの境界に割り当てられます。文字列定数は 2 バイトの境界に割り当てられ、
DATA
文中でない場合は、C ルーチンとのデータの受け渡しを容易にするため、その後に空文字が 1 つ付きます。
COMPLEX
複素数データは複素数の近似値です。複素数データ型
COMPLEX
は普通COMPLEX*8
と同義で、複素数を表す一対のREAL*4
の値です。前の要素は実部を、後の要素は虚部を表します。サイズを指定しない場合の
COMPLEX
項目のサイズはデフォルトで 8 バイトです。デフォルトでは 4 バイト境界に割り当てられます。しかし、特殊なオプションを指定してコンパイルすれば、これらのデフォルトを変更できます。(「データ型のサイズと整列条件」を参照)
COMPLEX*8 ©
複素数データ型
COMPLEX*8
は 普通COMPLEX
と同義ですが、ただしコンパイラオプションに関係なく、サイズは 8 バイトです。
COMPLEX*16
(倍精度複素数) ©複素数データ型
COMPLEX*16
は、DOUBLE COMPLEX
と同義ですが、コンパイラオプションに関係なく、サイズは常に 16 バイトです。
COMPLEX*32
(4 倍精度複素数) ©(SPARC のみ) 複素数データ型
COMPLEX*32
は 4 倍精度複素数です。これは一対のREAL*16
要素で構成されます。各要素には符号ビット、15 ビットの指数部、112 ビットの小数部があります。f77 では、REAL*16
要素は IEEE 規格に準拠します。
DOUBLE COMPLEX
©複素数データ型
DOUBLE COMPLEX
は、普通COMPLEX*16
と同義で、複素数を表す一対のDOUBLE PRECISION
(REAL*8
) の値です。前の要素は実部を、後の要素は虚部を表します。サイズを指定しない
場合の
DOUBLE COMPLEX
項目のサイズはデフォルトで 16 です。
DOUBLE PRECISION
倍精度データは実数の近似値です。倍精度データ型
DOUBLE PRECISION
は、REAL*8
と同義で、倍精度のデータを表現します。サイズを指定しない
場合の
DOUBLE PRECISION
項目のサイズはデフォルトで 8 バイトです。
DOUBLE PRECISION
の要素には符号ビット、11 ビットの指数部、52 ビットの小数部があります。f77 では、DOUBLE PRECISION
要素は、倍精度浮動小数点データに関する IEEE 規格に準拠します。データのレイアウトについては、「データの表現」を参照してください。
INTEGER
整数データ型
INTEGER
は符号付き整数値を表現します。サイズを指定しない
場合の
INTEGER
項目のサイズはデフォルトで 4 です。INTEGER
は 4 バイト境界に割り当てられます。しかし、特殊なオプションを指定してコンパイルすれば、これらのデフォルトを変更できます。(「データ型のサイズと整列条件」を参照)
INTEGER*2
©短い整数データ型
INTEGER*2
は符号付き整数値を表現します。INTEGER*2
型のオブジェクトだけを持つ式の型はINTEGER*2
です。この機能を使用すると、性能に影響することがありますので注意してください。総称関数は、デフォルトの整数型に従って、短いか、または長い整数を返します。
-i2
フラグを使用して手続きをコンパイルすると、その大きさに収まる整定数の全部と (サイズは明示されていない)INTEGER
型の変数の全部がINTEGER*2
型になります。整数値の組み込み関数の精度が総称関数の規則で決まらない場合、-i2
オプションが有効な時に優先される長さ (INTEGER*2
) を戻すものが選ばれます。-i2
オプションが有効なとき、LOGICAL
量のデフォルトの長さは 2 バイトです。通常の整数は、Fortran 77 の規則に従い、
REAL
変数と同じスペースを占めます。これらの整数は C 言語のlong
int
型相当であり、2 バイトの整数は C 言語のshort
int
型に相当します。これらの短い整数と論理量は、記憶領域割り当ての標準規則には従いません。
INTEGER*4
©整数データ型
INTEGER*4
は符号付き整数値を表現します。
INTEGER*8
©整数データ型
INTEGER*
8 は符号付き 64 ビット整数を表現します。これは、-dbl
オプションが設定されている場合のみです。
LOGICAL
論理データ型
LOGICAL
は、論理値 .TRUE
. または .FALSE
. を保持します。値 0 は .FALSE
. を表し、他の値はすべて .TRUE
. を表します。サイズを指定していない
場合の LOGICAL
項目の通常のデフォルトのサイズは 4 です。LOGICAL
は 4 バイト境界に割り当てられます。しかし、特殊なオプションを指定してコンパイルすれば、これらのデフォルトを変更できます。
LOGICAL*1
©1 バイトの論理データ型
LOGICAL*1
はBYTE
と同義で、以下の値のいずれかをとることができます。値については
LOGICAL
の定義と同様ですが、LOGICAL*1
は 1 文字または小さい整数を表現できます。例を示します。
LOGICAL*1 Bit3 / 8 /, C1 / 'W' /,& Counter / 0 /, Switch / .FALSE. /
LOGICAL*1
項目は 1 バイトの記憶領域を占めます。
LOGICAL*1
は 1 バイトの境界に割り当てられます。
LOGICAL*2
©データ型
LOGICAL*2
は、論理値 .TRUE
. または .FALSE
. をとります。値はLOGICAL
の場合と同様に定義されています。
LOGICAL*2
は 2 バイトの境界に割り当てられます。
LOGICAL*4
©論理データ型
LOGICAL*4
は、論理値 .TRUE
. または .FLASE
. をとります。値はLOGICAL
について定義されている値と同じです。
LOGICAL*8
©論理データ型
LOGICAL*8
は、論理値 .TRUE
. または .FLASE
. をとります。値はLOGICAL
データ型について定義されているものと同じです。
REAL
実数データは実数の近似値です。実数データ型
REAL
は通常、REAL*4
と同義で、実数データを表現します。サイズを指定していない
REAL
項目のデフォルトのサイズは通常 4 バイトです。REAL
は 4 バイト境界に割り当てられます。しかし、特殊なオプションを指定してコンパイルすれば、これらのデフォルトを変更できます。
REAL
の要素は、符号ビット、8 ビットの指数部、23 ビットの小数部で構成されます。f77
でのREAL
の要素は IEEE 規格に準拠します。
REAL*4
©データ型
REAL*4
はREAL
と同義ですが、コンパイラオプションに関係なく、サイズは常に 4 バイトです。
REAL*8
(倍精度実数)©データ型
REAL*8
はDOUBLE PRECISION
と同義ですが、コンパイラオプションに関係なく、サイズは常に 8 バイトです。
REAL*16
(4 倍精度実数)©(SPARC のみ) データ型
REAL*16
は 4 倍精度の実数です。
REAL*16
の要素は、符号ビット、15 ビットの指数部、112 ビットの小数部で構成されます。f77 でのREAL*16
の要素は、拡張された精度では IEEE 規格に準拠します。データ型のサイズと整列条件
記憶領域と整列条件は、常にバイト単位で規定されます。1 バイトに収まる値は、バイト単位で整列されます。
それぞれの型のサイズと整列条件は、コンパイラオプションの指定とプラットフォーム、さらに変数の宣言方法によって異なります。COMMON ブロックの最大整列条件は、4 バイト境界になります。
デフォルトのデータの整列条件や記憶領域の割り当ては、
-aligncommon
、-f
、-dalign
、-dbl_align_all
、-dbl
、-xmemalign
、-r8
、-i2
、-xtypemap
などのオプションを指定してコンパイルすることにより、変更することができます。このマニュアルでデフォルトについて説明するときは、これらのオプションは指定されていないものと想定します。個々のコンパイラオプションの詳細については、『Fortran ユーザーズガイド』を参照してください。
次の表に、デフォルトのサイズと整列条件についてまとめています。ただし、それ以外の型やオプションに関する項目は無視しています。
REAL*16
とCOMPLEX*32
は、SPARC のみ使用できます。64 ビット環境
(-xarch=v9
またはv9a
を使ってコンパイルする) では、表に 8/16 と記載されているように、デフォルトの整列条件は 16 バイト境界になります (8 バイトではありません)。- 配列と構造体はそれらの要素または欄によって整列条件が決まります。配列はその配列要素と同様に整列します。構造体は整列の幅が最大の欄と同様に整列します。
オプション
-i2
、-r8
、または-dbl
を指定してコンパイルすると、明示的なサイズ指定なしで出力される特定のデータ宣言のデフォルトが変更されます。
-i2
と-r8
を同時に使用しないでください。同時に使用した場合、予期しない結果が出ることがあります。REAL*16
とCOMPLEX*32
は、SPARC のみ使用できます。
-dbl
または-r8
を使用すると、INTEGER
およびLOGICAL
は、上記に示すように大きいスペースが割り当てられます。これは、整数項目と実数項目は同じ大きさの記憶領域を使用するという Fortran の要件を満たすための処置です。-r8
を使用すると 8 バイトが割り当てられますが、行われる計算は 4 バイトのみです。-dbl
を使用すると 8 バイトが割り当てられ、8 バイトの計算が実行されます。-dbl
と-r8
のどちらを使用しても結果は同じになります。-r8
または-dbl
を使用した場合の不利な点は、DOUBLE PRECISION
型データまでもQUAD
PRECISION
型に拡張してしまうため、性能が劣化する可能性があることです。
-r8
や-dbl
などの古いオプションよりも、順応性のある-xtypemap
オプションを使用することをお勧めします。-dbl
と-r8
に相当する-xtypemap
オプションは以下のとおりです。
- SPARC マシン
-dbl
は、-xtypemap=real:64,double:128,integer:64
と同じ-r8
は、-xtypemap=real:64,double:128,integer:mixed
と同じ
- x86
-dbl
は、-xtypemap=real:64,double:64,integer:64
と同じ-r8
は、-xtypemap=real:64,double:64,integer:mixed
と同じ
integer:mixed
は、8 バイトの整数の割り当てを示します。ただし行われる計算は 4 バイトのみです。SPARC では、さらに以下の 2 つの
-xtypemap
オプションを使用できます。
-xtypemap=real:64,double:64,integer:mixed
-xtypemap=real:64,double:64,integer:64これらはデフォルトの
REAL
とDOUBLE
を両方とも 8 バイトに割り当てるため、-r8
や-dbl
よりも実用的です。
INTEGER
とLOGICAL
は同等に処理され、COMPLEX
は 2 つのREAL
値として割り当てられます。また、DOUBLE COMPLEX
はDOUBLE
と同じ方法で割り当てられます。オプション
-f
または-dalign
(SPARCのみ) を指定すると、8 バイト、16 バイト、32 バイトのデータは、すべて 8 バイト境界に割り当てられます。オプション-dbl_align_all
を指定すると、すべてのデータが 8 バイト境界に割り当てられます。これらのオプションに依存するプログラムは、移植性に欠けることがあります。コンパイラオプションの詳細については、『Fortran ユーザーズガイド』を参照してください。
定数
定数とはプログラム単位を通して値が変化しないデータです。定数を表現する文字列の形式によりその定数の値とデータの型が決まります。(
PARAMETER
文で定義される名前付き定数の場合は、名前によってデータ型が決まります。)算術定数や論理定数に含まれる空白文字は定数の値に影響しません。文字定数に含まれる空白文字は定数の値に影響します。
複素定数 2 進定数 倍精度複素定数 8 進定数 倍精度定数 16 進定数 整定数 ホレリス定数 実定数
符号付き定数はプラスまたはマイナス符号が付いた算術定数です。符号なし定数は符号が付いていない算術定数です。
整数、実数、および倍精度のデータでは、ゼロは正数でも負数でもありません。符号付きのゼロと符号なしのゼロの値は同じです。
オプション
-i2
、-dbl
、-r8
、または-xtypemap
のいずれかを指定してコンパイルすると、整数、実数、複素数、および倍精度の各定数のデフォルトサイズが変更されます。これらのオプションについては、第 2 章「データ型とデータ項目」と『Fortran ユーザーズガイド』を参照してください。文字定数
文字列定数とはアポストロフィまたは引用符で囲まれた文字の列です。アポストロフィは規格ですが、引用符は規格外です。©
-xl
オプションを指定してコンパイルする場合、引用符は別の意味に解釈されるので、アポストロフィで文字列を囲む必要があります。アポストロフィで囲んだ文字列の中にアポストロフィを文字として含めるには、アポストロフィを 2 個続けます。引用符の場合も同様です。次にその例を示します。
'abc' "abc"'ain''t' "vi では ""h9Y と入力"文字列がどちらの区切り文字で始まる場合も、別の区切り文字は文字列の中に埋め込むことができます。この場合引用符を 2 つ続けたり、バックスラッシュ・エスケープを使用する必要はありません。表 2-3 を参照してください。
次にその例を示します。
"abc" "abc""ain't" 'vi では "h9Y と入力'空文字 ©
DATA
文中を除き、文字列定数の後ろには 1 個の 空文字を続けて、C ルーチンとのデータの受け渡しを容易にします。空文字だけの文字列定数を作ることもできます。このような空文字列定数は Fortran 規格外です。
demo% cat NulChr.fwrite(*,*) 'a', '', 'b'stopenddemo% f77 NulChr.fNulChr.f:MAIN:demo% a.outabdemo%ただし、空文字定数を文字変数に入れると、この変数には空白が含まれ長さは最小で 1 バイトになります。
demo% cat NulVar.fcharacter*1 x / 'a' /, y / '' /, z / 'c' /write(*,*) x, y, zwrite(*,*) len( y )enddemo% f77 NulVar.fNulVar.f:MAIN:demo% a.outa c1demo%エスケープシーケンス ©
C 言語の用法との互換性のために、以下の表に示すバックスラッシュ・エスケープシーケンスがあります。文字列の中にエスケープシーケンスを書くと、それに対応した文字に置き換えられます。
表 2-3 バックスラッシュ・エスケープシーケンス \n 改行 (Newline) \r キャリッジリターン \t タブ \b バックスペース \f 用紙送り (Form feed) \v 垂直タブ \0 空 (NULL) \' アポストロフィ (文字列を終了させない) \" 引用符 (文字列を終了させない) \\ \ \x (上記以外の任意の文字)
-xl
オプションを指定してコンパイルした場合、バックスラッシュ文字 (\) は普通の文字として扱われます。つまり、-xl
オプションを指定すると、上記のエスケープシーケンスを使用して特殊文字を入力することはできなくなります。技術的にはエスケープシーケンスは規格外ではありませんが、処理系によって定義が異なります。
複素定数
複素定数は実定数または整定数 (またはパラメータ定数 ©) を順序付けて対にしたものです。2 つの定数は括弧に入れ、コンマで区切ります。最初の定数は実部で、2 番目の定数は虚部です。複素定数
COMPLEX*8
は 8 バイトの記憶領域を使用します。
( 9.01, .603 )( +1.0, -2.0 )( +1.0, -2 )( 1, 2 )( 4.51, ) 無効 − 2 番目が必要
COMPLEX*16
定数倍精度複素定数
COMPLEX*16
は、実定数または整定数を順序付けて対にしたもので、一方の定数はREAL*8
で、他方の定数はINTEGER、REAL*4
またはREAL*8
です。©2 つの定数は括弧に入れ、コンマで区切ります。最初の定数は実部で、2 番目の定数は虚部です。倍精度複素定数
COMPLEX*16
は 16 バイトの記憶領域を使用します。
( 9.01D6, .603 )( +1.0, -2.0D0 )( 1D0, 2 )( 4.51D6, ) 無効 − 2 番目が必要( +1.0, -2.0 )DOUBLE COMPLEX
ではない −REAL*8
が必要
COMPLEX*32
(4 倍精度複素数) 定数(SPARC のみ) 4 倍精度複素定数 © は実定数または整定数を順序付けて対にしたもので、一方の定数は
REAL*16
で、他方の定数はINTEGER、REAL*4、REAL*8
またはREAL*16
です。©2 つの定数は括弧に入れ、コンマで区切ります。最初の定数は実部で、2 番目の定数は虚部です。4 倍精度複素定数
COMPLEX*32
© は 32 バイトの記憶領域を使用します。以下に 4 倍精度複素定数の例を示します (SPARC のみ)
。
( 9.01Q6, .603 )( +1.0, -2.0Q0 )( 1Q0, 2 )( 3.3Q-4932, 9 )( 1, 1.1Q+4932 )( 4.51Q6, ) 無効 − 2 番目が必要( +1.0, -2.0 ) 4 倍精度ではない −REAL*16
が必要整定数
整定数は、10 進数字列の前にプラス符号 (省略可能) またはマイナス符号が付いたものです。
制限事項
- 10 進数字以外の文字は使用できません (スペースは例外です)。
- 符号がない場合、その定数は負ではないとみなされます。
- 定数値の範囲は、整数を 64 ビットに拡張するオプションでコンパイルしない限り、
INTEGER*4
(-2147483648、2147483647) にならなくてはなりません。64 ビットに拡張するオプションでコンパイルした場合は、INTEGER*8
(-9223372036854775808、923372036854775807) になります。「データ型のサイズと整列条件」を参照してください。
-2147483648-2147483649 無効 − 小さすぎる、エラーメッセージ-100+199290022.71828INTEGER
ではない − 10 進小数点は使えない1E6INTEGER
ではない −E
は使えない29,002 無効 − コンマは使えない、エラーメッセージ21474836472147483648 無効 − 大きすぎる、エラーメッセージ代替 8 進表記 ©
整定数の指定には次のような代替 8 進表記を使用することもできます。整数の数字列の前に二重引用符 (") を付け、
-xl
オプションを指定してコンパイルしてください。このように表記された整定数は 8 進定数です。型はINTEGER
です。
次の 2 つの文は等価です。
JCOUNT = ICOUNT + "703JCOUNT = ICOUNT + 451整定数として 2 進、8 進、16 進またはホレリスのような型なし定数を指定することもできます。「型なし定数 (2 進、8 進、16 進)」を参照してください。
長い整数 ©
定数の範囲を
INTEGER*4
(-21474836、21474836) からINTEGER*8
(-9223372036854775808、923372036854775807) に拡張するオプションを指定してコンパイルします。この整定数はデータの型がINTEGER*8
の 8 バイト整数として格納されるかまたは引き渡されます。短い整数 ©
定数の引数が (-32768, 32767) の範囲内である場合、この引数は通常、データの型が
INTEGER*4
の 4 バイト整数に拡張されます。-i2
オプションを指定してコンパイルした場合、この引数はデータの型がINTEGER*2
の 2 バイト整数として格納されるかまたは引き渡されます。論理定数
論理定数とは真または偽の論理値です。論理定数の値は .
TRUE
. と .FALSE
. で、それ以外はありません。区切り文字のピリオドは必要です。論理定数は 4 バイトの記憶領域をとります。論理定数を実引数として使用する場合、この引数は 4 バイトで引き渡されます。
-i2
オプションを指定してコンパイルした場合、この引数は 2 バイトで引き渡されます。実定数
実定数は実際の数の近似値であり、正数、負数、ゼロのいずれかの値をとります。小数点か指数またはその両方を含んでいます。符号がない場合、その定数は負ではないとみなされます。
実定数
REAL*4
は 4 バイトの記憶領域を使用します。基本実定数
基本実定数は、プラス符号 (省略可能) またはマイナス符号、整数部、小数点、小数部の順で構成されます。
整数部と小数部はそれぞれ数字の列であり、どちらか一方を省略することはできますが、両方を省略することはできません。
+82.-32.90.98.5実指数部
実指数部は、文字
E
、プラス符号 (省略可能) またはマイナス符号、整数の順で構成されます。実指数部の例を示します。
E+12E-3E6実定数
実指数部は 10 のべき乗で示されます。実定数の値はこの 10 のべき乗と
E
の前にある定数との積です。
-32.-32.181.6E-97E31.6E12$1.0E2.0 無効 --$
は使えない、エラーメッセージ82REAL
ではない --10
進小数点か指数が必要29,002.0 無効 -- コンマは使えない、 エラーメッセージ1.6E39 無効 -- 大きすぎる、マシンの無限大が使用される1.6E-39 無効 -- 小さすぎる、いくらか精度が失われる
- プラス符号 (省略可能) またはマイナス符号、小数点、0 から 9 までの数字、および文字
E
以外の文字は使用できません。- 正規化された単精度浮動小数点値の近似値は、(1.175494E-38, 3.402823E+38) の範囲内でなければなりません。
REAL*8
(倍精度実) 定数倍精度実定数は実際の数の近似値であり、正数、負数、ゼロのいずれかの値をとります。符号がない場合、その定数は負ではないとみなされます。倍精度実定数は倍精度指数部と省略できる小数点を含みます。倍精度定数
REAL*8
は 8 バイトの記憶領域を使用します。REAL*8
表記は規格外です。©倍精度指数部
倍精度指数部は、文字
D
、プラス符号 (省略可能) またはマイナス符号、整数の順で構成されます。倍精度指数部は 10 のべき乗で示されます。倍精度定数の値はこの 10 のべき乗と
D
の前にある定数との積です。形式と解釈は、E
の代わりにD
が使用されることを除いて、実指数部の場合と同じです。
1.6D-97D3$1.0D2.0 無効 --$
は使えない、エラーメッセージ82 DOUBLE PRECISION ではない -- 10 進小数点が指数が必要29,002.0D0 無効 -- コンマは使えない、 エラーメッセージ1.8D308 無効 -- 大きすぎる、マシンの無限大が使用される1.0D-324 無効 -- 小さすぎる、いくらか精度が失われる
- プラス符号 (省略可能) またはマイナス符号、小数点、0 から 9 までの数字、空白、および文字
D
以外の文字は使用できません。- IEEE 形式の正規化された倍精度浮動小数点値の近似値は、(2.225074D-308, 1.797693D+308) の範囲内でなければなりません。
REAL*16
(4 倍精度実) 定数(SPARC のみ) 4 倍精度定数は基本実定数または整定数の後ろに 4 倍精度指数部が付いたものです。 「実定数」を参照してください。 ©
4 倍精度指数部は、文字
Q
、プラス符号 (省略可能) またはマイナス符号、整数の順で構成されます。4 倍精度定数は、正数、負数、ゼロのいずれかの値をとります。符号がない場合、その定数は負ではないとみなされます。
。
1.6Q-97Q33.3Q-49321.1Q+4932$1.0Q2.0 無効 --$
は使えない、エラーメッセージ82quad
ではない -- 指数が必要29,002.0Q0 無効 -- コンマは使えない、 エラーメッセージ1.6Q5000 無効 -- 大きすぎる、マシンの無限大が使用される1.6Q-5000 無効 -- 小さすぎる、いくつか精度が失われる形式と解釈は、
E
の代わりにQ
が使用されることを除いて、実定数の場合と同じです。
- プラス符号 (省略可能) またはマイナス符号、小数点、0 から 9 までの数字、空白、および文字
Q
以外の文字は使用できません。- IEEE 形式の正規化された 4 倍精度浮動小数点値の近似値は、(3.362Q-4932, 1.20Q+4932) の範囲内でなければなりません。
- 4 倍精度定数は 16 バイトの記憶領域をとります。
- 各 4 倍精度定数は 8 バイト境界に割り当てられます。
型なし定数 (2 進、8 進、16 進)
型なしの数値定数は、式の中でどのように使用されるかによってデータの型が決められるので、この名称が付けられています。©
この定数は使用されるまでは変換されません。ただし、f77 では、この定数は文字列と区別される必要があります。
この定数の一般形はアポストロフィで囲んだ数字の列の前に文字
B、O、X
またはZ
を付けます。B
は 2 進、O
は 8 進、X
またはZ
は 16 進の定数であることを示します。
DATA
文およびPARAMETER
文の中の 2、8、16 進定数の例を次に示します。
PARAMETER ( P1 = Z'1F' )INTEGER*2 N1, N2, N3, N4DATA N1 /B'0011111'/, N2/O'37'/, N3/X'1f'/, N4/Z'1f'/WRITE ( *, 1 ) N1, N2, N3, N4, P11 FORMAT ( 1X, O4, O4, Z4, Z4, Z4 )END
FORMAT
文の中の編集記述子に注意してください。O
は 8 進を、Z
は 16 進を表します。上記の整定数はすべて 10 進で 31 になります。
DATA
文およびPARAMETER
文以外の式での 2、8、16 進定数の例を次に示します。
INTEGER*4 M, ICOUNT/1/, JCOUNTREAL*4 TEMPM = ICOUNT + B'0001000'JCOUNT = ICOUNT + O'777'TEMP = X'FFF99A'WRITE(*,*) M, JCOUNT, TEMPENDこの例では
B'0001000'
とO'777'
はINTEGER*4
と定義され、X'FFF99A'
はREAL*4
と定義されています。実数に対して IEEE 形式の浮動小数点を使用すれば、アーキテクチャが異なっても与えられたビットパターンから生成される値は同じになります。上記の文は以下のように扱われます。
M = ICOUNT + 8JCOUNT = ICOUNT + 511TEMP = 2.35076E-38制御文字
制御文字は次の方法で入力できます。
CHAR
関数は規格内ですが、次の方法は規格外です。
CHARACTER BELL, ETX / X'03' /PARAMETER ( BELL = X'07' )型なし定数の代替表記
Fortran 77 の他のバージョンとの互換性のため、8 進と 16 進表記には以下の代替表記を使用することができます。この代替表記は 2 進数には無効です。また、
DATA
文またはPARAMETER
文の中では使用できません。8 進表記の場合、8 進数字の列をアポストロフィで囲み、その後ろに文字
O
を付けます。
'37'O37'O 無効 -- 最初のアポストロフィがない'37' 数値でない --O
の文字がない'397'O 無効 -- 無効な数字16 進表記の場合、16 進数字の列をアポストロフィで囲み、その後ろに文字
X
を付けます。
代替表記
'ab'X3fff'X'1f'X'1fX 無効 -- 後ろに続くアポストロフィがない'3f' 数値でない --X
がない'3g7'X 無効 -- 無効な数g
2 進、8 進および 16 進定数には、次の規則と制限事項があります。
- これらの定数は数値定数が許可される箇所ならどこでも使用できます。
- これらの定数には型がありません。これらの定数は、変数の型と一致させるための変換なしで変数に格納されますが、それを受け取る欄の適切な部分 (下位部または上位部) に格納されます。
- 定数を受け取るデータ型の桁数が定数の桁数よりも多い場合、左側にゼロが詰められます。
- 定数を受け取る欄のデータ型の桁数が定数の桁数よりも少ない場合、定数の桁の左側が切り捨てられます。その結果としてゼロ以外の桁が切り捨てられた場合、エラーメッセージが表示されます。
- 定数の先頭部分のゼロは無視されます。
- これらの定数として最大 8 バイトまでのデータを指定できます。
- 型なし定数を実引数として使用した場合、この実引数にはデータ型はありませんが、常に 4 バイトのデータとして引き渡されます。
- 2 進定数の場合、各桁は 0 か 1 でなければなりません。
- 8 進定数の場合、各桁は 0 から 7 までの数字でなければなりません。
- 16 進定数の場合、各桁は 0 から 9 までの数字か、
A
からF
まで、またはa
からf
までの英字でなければなりません。DATA
文以外ではこれらの定数は前後関係から決まる型として扱われます。型なし定数が 2 項演算子とともに使用された場合、その定数はもう一方のオペランドと同じデータ型になります (8.0
+'37'O
)。DATA
文ではこれらの定数は型なしの 2 進、16 進または 8 進定数として扱われます。ホレリス定数 ©
ホレリス定数は、符号なしのゼロ以外の整定数、文字
H
、印刷可能文字列の順で構成されます。整定数はスペースとタブも含めて印刷可能文字列中の文字数を指定します。Fortran 77 規格にはこの旧式のホレリス表記はありませんが、古いプログラムとの互換性を維持するためにホレリス機能を装備することをお勧めします。
ホレリスデータを文字列定数の代わりに使用することができます。また、ホレリスデータを
IF
文の条件に使用したり、DATA
文や代入文中の変数 (文字変数以外) を初期化するのにも使用できますが、このような使用法は勧められませんし、すべて規格外です。ホレリスデータは型なし定数です。
CHARACTER C*1, CODE*2INTEGER TAG*2DATA TAG / 2Hok /CODE = 2HnoIF ( C .EQ. 1HZ ) CALL PUNT
- 文字数には実際上の制限はありません。
- 文字を継続行に続けることはできますが、複雑な方法になります。短い標準固定フォーマットの行は 72 桁目まで右に空白が詰められますが、短いタブフォーマットの行は改行で終わります。
- ホレリス定数が 2 項演算子とともに使用された場合、その定数はもう一方のオペランドと同じデータ型になります。
- ホレリス定数を変数に代入した場合、その定数の長さが変数のデータ型の長さより短かければ、スペース (ASCII 32) が右側に追加されます。
- ホレリス定数または変数の長さが変数のデータ型より長い場合は、文字の右側が切り捨てられます。
Fortran 95 のスタイルによる定数 ©
Sun WorkShop Fortran 77 コンパイラは、データ項目のサイズのリテラルな指定を可能にする整数と実数の定数の Fortran 95 のスタイルによる構文を認識します。Fortran 95 の用語の用法では、定数のリテラルには、末尾のアンダースコア (オプション) に続けて「kind type parameter」を入れることができます。©
Sun Fortran 77 における実装では、「kind type parameter」に使用可能な数値は、1、2、4、8、16 に限定され、それによってリテラルな定数のデータサイズをバイト単位で指定することができます。
12_8
8 バイトの整定数を指定、値 = 1212.012_16
16 バイトの実定数を指定、値 = 12.0121.345E-10_8 8 バイトの実定数を指定、値 = 1.345E-10(-1.5_8,.895E-3_8)
8 バイトの実部と虚部を持つ複素定数を指定複素数の定数では、実部と虚部は、別々の kind type parameter (1.0_8、2.0_4) で指定されますが、最終的なデータ項目は、同じサイズの実部と虚部から構成されることになります。これは大きい値を指定した方のサイズになります。
このような構成は、次の例からも分かるように、特定のデータ型が必要なサブプログラムを、定数を引数として呼び出す際に役立ちます。
call suby(A,1.5_8,0_8,Y)...subroutine suby(H0,M,N,W)INTEGER *8 M,N,...変数
変数とは記憶場所と対になっている英字名です。変数は、名前、値、および型を持ちます。その記憶場所に格納されているデータが変数の値です。配列もしくは配列要素、記録、または記録欄は変数には含まれないことに注意してください。したがって、この定義は通常の「変数」という語の使用法よりも限定的です。
変数の型は型宣言文で指定できます。型が型宣言文で明示的に指定されない場合、その変数名の最初のアルファベットによって型が暗黙的に決められます。この場合、通常のデフォルトの暗黙の型宣言か、
IMPLICIT
文で指定された暗黙の型宣言に従います。データの型宣言規則の詳細については、 「データの型」を参照してください。プログラム実行中のある時点での変数は定義されているか未定義であるかのどちらかです。変数が予測可能な値を持つ場合は変数は定義されており、そうでない場合は未定義です。副プログラムが終了すると、定義されていた変数が未定義になることがあります。
代入文、入力文、または
DATA
文で変数を定義することができます。DATA
文で変数に値を割り当てると、その変数は初期定義されたことになります。2 つの変数が同じ記憶場所に関連付けられている場合、それら 2 つの変数は関連付けられています。
EQUIVALENCE
文、COMMON
文、またはMAP
文を使用すれば変数を関連付けることができます。実引数と仮引数を使用しても変数を関連付けることができます。配列
配列とは同じ型の要素の集合に名前を付けたものです。配列は空ではない一連のデータであり、連続する記憶領域を占めます。配列は、名前、一連の要素、および型を持ちます。
配列要素は一連のデータのメンバーの 1 つです。各記憶場所は配列の 1 要素を保持します。
配列要素名は添字で修飾された配列名です。詳しくは 「配列の添字」を参照してください。
配列宣言子
配列宣言子の構文は次のとおりです。
a (
d [, d ] ... )
1 つの配列は、1 プログラム単位 (主プログラム、サブルーチン、関数、または共通ブロック)内の 1 配列宣言に 1 度だけ指定できます。同じ単位内に複数または重複した配列宣言がある場合、コンパイラはそれらの宣言をエラーとして通知します。
配列の次元数は寸法宣言子の数です。次元数の最小は 1、最大は 7 です。大きさ引き継ぎ配列の場合、最後の寸法がアスタリスクで指定されます。
下限はその次元の最初の要素を示し、上限はその次元の最後の要素を示します。1 次元の配列では上下限は配列の最初と最後の要素です。
REAL V(-5:5)上記の例で
V
は 1 次元で 11 の要素を持つ実数の配列です。最初の要素はV(-5)
で、最後の要素はV(5)
です。下限の指定を省略した (その場合、下限は 1) 配列の例を次に示します。
REAL V(1000)上記の例で
V
は 1 次元で 1,000 個の要素を持つ実数の配列です。最初の要素はV(1)
で、最後の要素はV(1000)
です。配列は最大で 7 次元にすることができます。次にその例を示します。
REAL TAO(2,2,3,4,5,6,10)
REAL A(3:5, 7, 3:5), B(0:2)
CHARACTER M(3,4)*7, V(9)*4配列
M
は 12 個の要素を持ち、各要素は 7 文字からなります。
配列V
は 9 個の要素を持ち、各要素は 4 文字からなります。
- 上下限とも、負数、ゼロ、正数を指定できます。
- 上限は下限よりも大きいか等しくなければなりません。
- 上下限が 1 つしか指定されない場合、上限の指定とみなされ、下限は 1 になります。
- 大きさ引き継ぎ配列は最後の次元の上限がアスタリスクで指定されます。
- 上下限は整数式で、その式の各オペランドは、定数、仮引数、または共通ブロック内の変数です。配列の引用やユーザー定義の関数は指定できません。
整合配列
整合配列とは仮引数として指定された配列、あるいは、1 つ以上の次元または上下限が整変数の式として指定された局所配列 © です。その整変数は、それ自身が仮引数または共通ブロック内の変数になります。
整合配列は、通常の
DIMENSION
文、または型宣言文で宣言できます。f77 では整合配列はRECORD
文でも宣言できます。ただし、そのRECORD
文が構造体宣言ブロックの中にはないとします。
SUBROUTINE POPUP ( A, B, N )COMMON / DEFS / M, LREAL A(3:5, L, M:N), B(N+1:2*N) !仮引数の配列REAL C(N+1,2*N) !局所配列
- 整合配列の大きさは対応する実引数の大きさを超えてはいけません。
- 一連の呼び出しの最初の呼び出し元では、対応する配列の次元が定数で決定されていなければなりません。
COMMON
文で整合配列を宣言することはできません。配列がルーチンに対して局所指定される場合は、そのルーチンの入り口でメモリーが割り当てられ、呼び出し元への戻りで割り当てが解除されます。©
大きさ引き継ぎ配列
大きさ引き継ぎ配列とは仮引数として指定された配列であり、かつ、最後の次元の上限がアスタリスクで指定された配列です。
大きさ引き継ぎ配列は、通常の
DIMENSION
文、COMMON
文、または型宣言文で宣言できます。
RECORD
文における大きさ引き継ぎ配列の宣言。ただしそのRECORD
文が構造体宣言ブロックの中にあってはいけません。- 入出力文における内部ファイルの装置識別子としての大きさ引き継ぎ配列の指定。
- 入出力文における実行時の書式指定子としての大きさ引き継ぎ配列の指定。
最後の次元の上限がアスタリスクで指定された大きさ引き継ぎ配列の例を次に示します。
SUBROUTINE PULLDOWN ( A, B, C )INTEGER A(5, *), B(*), C(0:1, 2:*)添字なしの配列名
添字なしの配列名はその配列全体を示し、以下の文の中で指定できます。
EQUIVALENCE
文では、添字なしの配列名はその配列の最初の要素を示します。配列の添字
添字の形式
添字は括弧で囲まれた添字式の並びです。配列の各次元に対して 1 つの添字式を指定しなければなりません。
- ( s [, s] ... )
たとえば、次のような宣言子で 2 × 3 の配列を宣言しているとします。
REAL M(2,3)上記について、次のようにすれば、その配列の特定の要素に値を代入することができます。
M(1,2) = 0.0上記の文は、配列
M
の行 1、列 2 の要素に 0.0 を代入しています。添字式
- 添字式は整数式、実数式、複素式、論理式またはバイト式です (FORTRAN 77 規格に従う場合は整数式でなければなりません)。
- 添字式に配列要素の引用や関数の引用を含めることができます。
- 関数の引用が評価された結果、同じ添字内の他の添字式の値を変更してはいけません。
- 各添字式は配列の対応する次元への索引です。
- 各添字式の値は配列の対応する次元の上下限の範囲内になければなりません。
- (L1,…,Ln) という形式の添字 (各 Li は対応する次元の下限) はその配列の最初の要素を引用します。
- (U1,…,Un) という形式の添字 (各 Ui は対応する次元の上限) はその配列の最後の要素を引用します。
- 配列要素
A(n)
は必ずしも配列A
の n 番目の要素であるとは限りません。
REAL V(-1:8)V(2) = 0.032 ビット環境では、添字式が INTEGER*4 の範囲を越えることはできません。添字式が範囲内 (-2147483648, 2147483647) にない場合、結果は予測できません。64 ビット環境用としてコンパイルする場合は、
INTEGER*8
の添字式を使用することができます。配列の順序付け
配列要素はイメージ的には通常、最初の添字を行番号、2 番目の添字を列番号として並べられます。これは伝統的な数学の nxm 行列の表記に対応します。
an,1 an,2 ...
an,m
INTEGER*4 A(3,2)
A(1,1) A(1,2) A(2,1) A(2,2) A(3,1) A(3,2)
たとえば配列
A
の場合、その要素はメモリー上に次のように配置されます。
A(1,1)
A(2,1)
A(3,1)
A(1,2)
A(2,2)
A(3,2)
部分列
文字データは連続した 1 個以上の文字です。部分列とは、文字変数、文字配列要素、または構造体の記録の文字欄の中の連続した部分のことです。
a
(
s[,
s]
... )
([
e1]
:[
e2]
)
v
文字変数名
a (s [, s] ... ) 文字配列要素名 e1 部分列の左端の文字の位置 e2 部分列の右端の文字の位置
e1 と e2 は整数式です。32 ビット環境では、整数式が INTEGER*4 の範囲を越えることはできません。整数式が範囲内 (-2147483648, 2147483647) にない場合、結果は予測できません。64 ビット環境用としてコンパイルする場合は、部分列の文字位置を示す式を
INTEGER*8
の範囲内で指定することができます。次の例は、文字変数名
S
のI
番目の文字を最初の文字とし、L
番目の文字を最後の文字とする文字列です。
S(I:L)次の例は、配列要素
A(J,K)
のM
番目の文字を最初の文字とし、N
番目の文字を最後の文字とする文字列です。
A(J,K)(M:N)
- 部分列の中の文字位置は左から右へと番号が付けられます。
- 文字列の最初の文字位置には番号 1 (0 ではない) が付けられます。
- 部分列の最初と最後の文字位置は整数式で表します。
- 最初の式を省略すると 1 になります。
- 2 番目の式を省略すると宣言された文字列の長さになります。
- 0 < I ≦ L ≦ 宣言された長さ (I は部分列の最初の位置、L は最後の位置) という条件に従っていない場合、結果は未定義となります。
- 部分列は代入文の左辺と右辺で使用できます。また、手続きの実引数としても使用できます。
- 部分列はオーバーラップすることはできません。
ASTR
(2:4)
=
ASTR
(3:5)
は不正です。以下に部分列の例を示します。行 2、列 3 の要素の値は
e23
です。
構造体
配列は同じ型の要素の集まりですが、構造体は必ずしも同じ型ではない要素の集まりです。
配列の要素は数値の添字を使用することにより引用されますが、構造体の要素は要素 (または欄) 名を使用することにより引用されます。
構造体宣言では、記録を構成する欄の名前、型、サイズ、および順序を指定して記録の形式を定義します。構造体が定義されて名前が付けられると、以下で説明するようにその構造体を
RECORD
文で使用することができます。構造体宣言の構文を以下に示します。構造体宣言
欄の並び
指定された構造体の欄の並び
欄宣言
記録内の欄を定義する欄宣言の定義は次項を参照
欄宣言
STRUCTURE /PRODUCT/INTEGER*4 IDCHARACTER*16 NAMECHARACTER*8 MODELREAL*4 COSTREAL*4 PRICEEND STRUCTURE
上記の例では、PRODUCT
という名前の構造体を5つの欄ID、NAME、MODEL、COST
およびPRICE
で構成するように定義しています。欄の並びの例は 「構造体の中の構造体」を参照してください。構造体の規則と制限事項
- 名前はスラッシュで囲みます。入れ子にした構造体でのみ名前を省略できます。
- スラッシュがある場合は名前もなければなりません。
- 欄の並びは入れ子にした構造体の中だけで指定できます。
- 欄宣言は必ず 1 つ以上なければなりません。
- 各構造体名はすべての構造体を通じて一意に決められなければなりません。しかし、構造体名を他の構造体の欄名に使用したり、変数名として使用することはできます。
STRUCTURE
文からEND STRUCTURE
文までの間では欄宣言文とPARAMETER
文だけが使用できます。構造体宣言ブロック内にあるPARAMETER
文はその外側にあるPAPAMETER
文と同じ効果を持ちます。欄の規則と制限事項
型宣言のある欄は通常の Fortran 77 の型宣言文と同じ構文を使用し、
f77
のすべての型が使用できます。以下の規則と制限事項に従います。
- 必要な配列の形状指定は型宣言文の中で行わなければなりません。欄名に対して
DIMENSION
文は無効です。- 欄名として擬似名
%FILL
を指定できます。%FILL
は Fortran 77 の他のバージョンとの互換性のために提供されています。f77
では整列の問題は考慮されているので%FILL
を使用する必要はありません。擬似名%FILL
は、ある特定のサブルーチン内に引用できない欄を作りたい場合に役に立つ機能です。%FILL
の機能は、指定されたサイズと型の欄を作り、その欄の引用を不可能にすることだけです。- すべての欄名は明示的に型宣言されなければなりません。
STRUCTURE
宣言の文には、IMPLICIT
文も、暗黙のI、J、K、L、M
およびN
の規則も適用されません。- 欄宣言の中では、整合配列または大きさ引き継ぎ配列を使用したり、
CHARACTER
宣言の文字の長さを (*
) で指定することはできません。構造体宣言での欄のオフセット n は、1 つ前にある欄のオフセットにその前欄の長さを加算した値です。整列条件を満たすための調整が行われた場合は、さらにその分が補正されます。記憶領域割り当ての要約については、「データの表現」を参照してください。
記録宣言
RECORD
文は、変数が指定された構造体の記録であることを宣言するか、あるいは配列が指定された構造体の記録の配列であることを宣言します。
記録の並び
変数、配列、または、形状が指定された配列の、コンマで区切られた並び
前の
STRUCTURE
文の例を用いたRECORD
の例を次に示します。
RECORD /PRODUCT/ CURRENT, PRIOR, NEXT, LINE(10)3 つの変数
CURRENT、PRIOR
およびNEXT
はそれぞれPRODUCT
構造体を持つ記録で、LINE
はその記録が 10 個集まった配列です。
- 各記録はメモリー上では分離して割り当てられます。
- 明示的に初期化されない限り、記録の初期値は未定義です。
- 記録、記録欄、記録配列、および記録配列要素を実引数および仮引数として使用できます。記録を引数として渡す場合、その欄は型、順序、および寸法が一致していなければなりません。呼び出す側と呼び出される側の手続きで、記録宣言は一致していなければなりません。共用体宣言の内部ではマップ欄の順序に意味はありません。「UNION と MAP」を参照してください。
- 記録欄は
COMMON
文では指定できません。- 記録と記録欄は
DATA
文、EQUIVALENCE
文、またはNAMELIST
文 では指定できません。記録欄はSAVE
文では指定できません。記録と欄の引用
記録全体または記録内の個々の欄を引用することができます。また、構造体は入れ子可能なので欄自身を構造体にすることができます。したがって、欄内の欄を引用したり、そのまた内側の欄を引用することができます。
欄名
直前 (左側) に指定されている記録の中にある欄の名前
前記の 2 つの例の構造体と記録を用いた引用例を以下に示します。
...RECORD /PRODUCT/ CURRENT, PRIOR, NEXT, LINE(10)...CURRENT = NEXTLINE(1) = CURRENTWRITE ( 9 ) CURRENTNEXT.ID = 82
- 最初の代入文が記録全体 (5 つの欄全部) を別の記録にコピーします。
- 2 番目の代入文が記録全体を記録の配列の最初の要素にコピーします。
WRITE
文が記録全体を出力します。- 最後の文が記録の
ID
を 82 に設定しています。構造体と記録の宣言、および記録と欄への代入の例を以下に示します。
部分構造体の宣言
構造体の中の欄をさらに構造体にすることができます。このような欄を部分構造体と呼びます。部分構造体は次のどちらかの方法で宣言します。
構造体の中の記録
入れ子にした構造体宣言とは、構造体宣言または共用体宣言の中に含まれている構造体宣言のことです。以前に定義された記録を構造体宣言の中で使用することができます。
あらかじめ定義された記録
PRODUCT
を使用して構造体SALE
を定義する例を以下に示します。
STRUCTURE /SALE/CHARACTER*32 BUYERINTEGER*2 QUANTITYRECORD /PRODUCT/ ITEMEND STRUCTURE上記の例では、構造体
SALE
はBUYER、QUANTITY
およびITEM
の 3 つの欄を含んでいます。ITEM
は構造体/PRODUCT/
をもつ記録です。構造体の中の構造体
/PRODUCT/
があらかじめ宣言されていない場合、SALE
の宣言の中で宣言することができます。以下に例を示します。
STRUCTURE /SALE/CHARACTER*32 BUYERINTEGER*2 QUANTITYSTRUCTURE /PRODUCT/ ITEMINTEGER*4 IDCHARACTER*16 NAMECHARACTER*8 MODELREAL*4 COSTREAL*4 PRICEEND STRUCTUREEND STRUCTUREこの例でも、前記の例と同じく、構造体
SALE
は 3 つの欄BUYER、QUANTITY
およびITEM
を含みます。欄ITEM
は「構造体の宣言」で定義された欄の並び (この場合は要素数が 1 個の並び) の例です。それぞれの構造体のサイズと複雑さにより、与えられた状況に最も適した部分構造体宣言の方式を決めます。
部分構造体内の欄の引用
部分構造体 (前記の例の
PRODUCT
およびSALE
が現行プログラム単位内で定義されているとする) の欄を引用する例を次に示します。
...RECORD /SALE/ JAPAN...N = JAPAN.QUANTITYI = JAPAN.ITEM.ID...部分構造体の規則と制限事項
- 部分構造体に対して少なくとも 1 つの欄名を定義しなければなりません。
- 同じ入れ子レベルの 2 つの欄が同じ名前を持つことはできません。異なるレベルにある欄であれば同じ名前を持つことができます。ただし、そのようにするとプログラミング上で問題が生じやすくなります。
- 擬似名
%FILL
を使用して記録内で欄を整列させることができます。これは名前なしの空の欄を作ります。- どの入れ子レベルでも構造体がそれ自身を部分構造体として含むことは許可されません。
UNION と MAP
共用体宣言は実行時に記憶領域を共有する欄のグループを定義します。
構文
UNIONマップ宣言マップ宣言[マップ宣言]
...[マップ宣言]
END UNION
MAP欄宣言[欄宣言]
...[欄宣言]
END MAPマップ内の欄
マップ宣言は、共用体の中に代替の欄グループを定義します。実行中のある時点では、どちらか一方のマップが共有の記憶場所に関連付けられています。マップ内の欄を引用すると、それ以前に記憶場所に関連付けられていたマップの欄グループは未定義になり、新しく引用された欄が属するマップの欄グループが記憶場所を引き継ぎます。共用体が使用するメモリー量はその共用体の中の最大のマップが使用するメモリー量です。
以下の例では、構造体
/STUDENT/
がNAME、CLASS
およびMAJOR
か、もしくはNAME、CLASS、CREDITS
およびGRAD_DATE
を含むように宣言しています。
STRUCTURE /STUDENT/CHARACTER*32 NAMEINTEGER*2 CLASSUNIONMAPCHARACTER*16 MAJOREND MAPMAPINTEGER*2 CREDITSCHARACTER*8 GRAD_DATEEND MAPEND UNIONEND STRUCTURE変数
PERSON
が上記の例の構造体/STUDENT/
を持つように定義した場合、PERSON
·MAJOR
は最初のマップの欄を引用し、PERSON
.CREDITS
は 2 番目のマップの欄を引用します。2 番目のマップの欄の変数が初期化された後でプログラムが変数PERSON
.MAJOR
を引用した場合、最初のマップが有効になり、2 番目のマップの各変数は未定義になります。ポインタ
POINTER
文は変数とポインタの対を設定します。©
各ポインタには対になる変数のアドレスが含まれています。構文の規則
POINTER ( p1, v1 ) [, ( p2, v2 ) ... ]ポインタ基底付き変数とは、
POINTER
文で指定されるポインタと対になっている変数です。ポインタ基底付き変数は、通常は単に基底付き変数または指示先と呼ばれます。ポインタはアドレスを含んでいる整変数です。(POINTER 文で指定する変数名は、コンパイラでは VOLATILE と見なされます)
POINTER ( P, V )上記の例で、
V
は指示先、P
はそれに関連付けられたポインタです。その他の例については、「POINTER」を参照してください。
ポインタの使用法
ポインタ基底付き変数を使用するには以下の手順が必要です (最初の 2 つの手順はどちらを先に実行しても構いません)。
1.POINTER
文でポインタ基底付き変数とポインタの対を定義します。2. ポインタ基底付き変数の型を定義します。
- ポインタそのものは整数型になりますが、型宣言には使用しません。
3. 適切な大きさと型を持つ記憶領域のアドレスをポインタに設定します。
- 通常は、他にはポインタに対する明示的な処置は必要ありません。
4. ポインタ基底付き変数を引用します。
- 一般的な Fortran 77 の文でポインタ基底付き変数を使用すれば、この変数のアドレスは必ずそれに関連付けられているポインタから取られます。
アドレスとメモリー
ポインタ基底付き変数が定義された時には、その変数には記憶領域が割り当てられていません。通常、ユーザーは自分の責任で適切な型とサイズを持つ変数のアドレスを用意し、普通の代入文または
DATA
文によりそのアドレスをポインタに割り当てなければなりません。
loc()
、malloc()
、およびfree()
の各ルーチンは、メモリーアドレスとポインタとの関連付けと関連解除を行います (これらのルーチンについては、第 6 章「組み込み関数」を参照)。64 ビット環境用としてコンパイルする場合は、
POINTER
文で宣言されるポインタはINTEGER*8
の値になります。
LOC()
関数によるアドレスの獲得アドレスは組み込み関数
LOC()
から得ることができます。
LOC()
関数を使用してアドレスを得る例を以下に示します。
* ptr1.f: LOC() を介してアドレスを割り当てるPOINTER ( P, V )CHARACTER A*12, V*12DATA A / 'ABCDEFGHIJKL' /P = LOC( A )PRINT *, V(5:5)END上記の例では、
CHARACTER
文はA
には 12 バイトの記憶領域を割り当てますが、V
には記憶領域を割り当てません。V
はポインタ基底付き変数なのでV
の型だけを指定します。次にA
のアドレスがP
に割り当てられるので、V
を使用するとポインタP
を通してA
が引用されます。このプログラムはE
を出力します。64 ビット環境用としてコンパイルする場合は、
LOC()
によってINTEGER*8
の値が戻されます。受け取る変数は、アドレスが切り捨てられる可能性を避けるため、ポインタまたはINTEGER*8
のどちらかの変数でなければなりません。
MALLOC()
関数による記憶領域とアドレスの獲得関数
MALLOC()
は記憶領域を割り当て、その領域の開始アドレスを戻します。この関数の引数は整数で、割り当てるメモリーの量をバイト単位で指定します。この関数が正常に実行されるとその領域の最初の項目へのポインタを戻し、失敗すると整数 0 を戻します。記憶領域は初期化されません。64 ビット環境のコンパイルでは、
LOC
() によってINTEGER*8
の値が戻されます。受け取る変数は、アドレスが切り捨てられる可能性を避けるため、ポインタまたはINTEGER*8
のどちらかの変数でなければなりません。
MALLOC
を使用してポインタに記憶領域を割り当てる例を以下に示します。
COMPLEX ZREAL X, YPOINTER ( P1, X ), ( P2, Y ), ( P3, Z )...P1 = MALLOC ( 10000 )...上記の例では、
MALLOC
() が 10,000 バイトのメモリーを割り当て、そのメモリーブロックのアドレスとポインタP1
を関連付けています。
FREE()
サブルーチンによる記憶領域の割り当て解除サブルーチン
FREE()
は先にMALLOC()
により割り当てられた記憶領域を解放します。FREE()
に与える引数は、MALLOC()
により返されたポインタでなければなりません。これはプログラマがFREE()
に与える必要があります。記憶領域はメモリーマネージャに戻され、メモリーマネージャはプログラマがその記憶領域を使用できないようにします。
POINTER ( P1, X ), ( P2, Y ), ( P3, Z )...P1 = MALLOC ( 10000 )...CALL FREE ( P1 )...上記の例では、
MALLOC()
が 10,000 バイトのメモリーを割り当て、そのメモリーがポインタP1
に関連付けられます。その後、FREE()
がその同じ 10,000 バイトをメモリーマネージャに戻しています。特記事項
malloc()
、loc()
、free()
を使用してポインタとメモリー割り当てを操作する場合は、以下の点に特に注意してください。
- ポインタはコンパイラによって自動的に整数型に宣言されます。プログラマが自分でポインタを型宣言してはいけません。
- ポインタ基底付き変数自身をポインタにすることはできません。
- ポインタ基底付き変数は構造体も含めてどの型にすることもできます。
- ポインタ基底付き変数は、型宣言文の中でサイズが指定されていても、宣言された時点では記憶領域は割り当てられません。
- ポインタ基底付き変数を仮引数として使用したり、
COMMON
文、EQUIVALENCE
文、DATA
文、またはNAMELIST
文の中で使用することはできません。- 主プログラム内では、ポインタ基底付き変数の寸法式は定数式でなければなりません。サブルーチンと関数内では、仮引数に対するのと同じ規則がポインタ基底付き配列変数に対して適用されます。つまり、式の中に仮引数と共通ブロックの中の変数を含むことができます。式の中のすべての変数は、サブルーチンまたは関数の呼び出し時に整数値で定義されなければなりません。
- 32 ビット環境では、アドレス式が INTEGER*4 の範囲を超えることはできません。
式が範囲内 (-2147483648, 2147483647) にない場合、結果は予測できません。- 64 ビット環境用としてコンパイルする場合は、
malloc64()
を使用して 64 ビットのアドレス領域にアクセスします。ルーチンmalloc64()
は、INTEGER*8
の引数を取り、64 ビットのポインタ値を戻します。64 ビットのプログラムでは、POINTER
文で定義されたポインタは 64 ビットのINTEGER*8
になります。『Fortran ライブラリ・リファレンス』およびmalloc
(3F) のマニュアルページを参照してください。最適化とポインタ
ポインタを使用すると、大域的オプティマイザの処理の前提範囲が限定されます。次の 2 つの場合を比較してください。
- ポインタが使用されていない場合、サブルーチンまたは関数の呼び出しによって変更されるのは、共通ブロックの変数、または引数として渡される変数だけであることをオプティマイザは認識しています。
- ポインタが使用されている場合、この前提はもはや無効となります。なぜなら、ルーチンは引数のアドレスを取り出して共通ブロックにあるポインタの中に保存することができ、以後このポインタを自分自身または他のルーチンの呼び出しで使用するからです。
したがって、オプティマイザは、サブルーチンまたは関数の呼び出しにおいて引数として渡される変数が、他の呼び出しにより変更される可能性を仮定しなければなりません。このようなポインタの無制約な使用は、ポインタを使用しない大部分のプログラムに対しても最適化のレベルを低下させることになります。
一般的なガイドライン
2 番目の選択には更に選択肢があります。ポインタをルーチンに局所的に使用し、それは最適化せず、計算を行うルーチンのみを最適化します。呼出しルーチンを別々のファイルに入れることにより、あるルーチンは最適化し、あるものは最適化しないということができます。
REAL A, B, V(100,100) このプログラム単位は、POINTER ( P, V ) アドレスを取得して渡す以外にP = MALLOC(10000)P
では何も行わない...CALL CALC ( P, A )...ENDSUBROUTINE CALC ( ARRAY, X )...RETURNENDレベル
-04
でCALC
のみを最適化したい場合は、CALC
内ではポインタを使用しないでください。注意事項
次のようなコーディングの仕方では、レベル
-03
または-04
での最適化で問題が生じる可能性があります。
- プログラム単位が、ポインタで算術計算を行う。
- 副プログラムが各呼び出し間で引数のアドレスを保存する。
- 関数がポインタ引数の値を戻さずに、引数のアドレスを戻す。
- ポインタを通して変数の引用があるが、その変数アドレスは
LOC()
またはMALLOC()
から明示的に得られたものではない。
COMMON A, B, CPOINTER ( P, V )P = LOC(A) + 4 最適化を行うと、ここで問題が起こる可能性がある...コンパイラは、
P
を通した引用によりA
が変更されると仮定しますが、B
が変更されることは仮定しません。この仮定により誤ったコードが生成される可能性があります。
サン・マイクロシステムズ株式会社 Copyright information. All rights reserved. |
ホーム | 目次 | 前ページへ | 次ページへ | 索引 |