FORTRAN 77 言語リファレンス ホーム目次前ページへ次ページへ索引


第 2 章

データ型とデータ項目

この章では、Sun FORTRAN 77 のデータ型とデータ構造について説明します。

規格外の機能には、普通小さな塗り潰した菱形 (©) が付きます。

データの型

通常、定数、定数式、変数、配列、配列要素、部分列、および関数は、 型を持つデータを表しています (型のない定数は例外です)。

一方、プログラムまたはサブルーチン、初期値設定副プログラム、共通ブロック、変数群、構造化記録は、データ型をもっていません。

データの型に関する規則

名前により型が決定されます。つまりデータや関数の名前により、以下のデータ型規則に従って、明示的または暗黙的にデータの型が決まります。

配列要素

配列要素の型は配列名の型と同じです。

関数

組み込み関数は、あらかじめ指定された型を持っています。組み込み関数には、明示的な型宣言文は必要ありませんが、型宣言をすることもできます。総称関数には、前もって決められた型はなく、「組み込み関数」で説明しているように、引数の型で決まります。

外部関数の型は以下のいずれかの方法で指定できます。

例:型宣言文で明示的に名前を指定します。

	FUNCTION F ( X ) 
	INTEGER F, X 
	F = X + 1 
	RETURN 
	END

例:FUNCTION 文で明示的に名前を指定します。

	INTEGER FUNCTION F ( X ) 
	INTEGER X 
	F = X + 1 
	RETURN 
	END 

例:変数の場合のように名前で暗黙的に示します。

	FUNCTION NXT ( X ) 
	INTEGER X 
	NXT = X + 1 
	RETURN 
	END 

暗黙の型宣言は関数の型にも有効です。デフォルトでの暗黙の型宣言または 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 規格に準拠します。

COMPLEX*32 項目のサイズは 32 バイトです。

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*2 は 2 バイトを占めます。

INTEGER*2 は 2 バイト境界に割り当てられます。

INTEGER*4 ©

整数データ型 INTEGER*4 は符号付き整数値を表現します。

INTEGER*4 は 4 バイトを占めます。

INTEGER*4 は 4 バイト境界に割り当てられます。

INTEGER*8 ©

整数データ型 INTEGER*8 は符号付き 64 ビット整数を表現します。これは、-dbl オプションが設定されている場合のみです。

INTEGER*8 は 8 バイトを占めます。

INTEGER*8 は 8 バイト境界に割り当てられます。

LOGICAL

論理データ型 LOGICAL は、論理値 .TRUE. または .FALSE. を保持します。値 0 は .FALSE. を表し、他の値はすべて .TRUE. を表します。

サイズを指定していない場合の LOGICAL 項目の通常のデフォルトのサイズは 4 です。LOGICAL は 4 バイト境界に割り当てられます。しかし、特殊なオプションを指定してコンパイルすれば、これらのデフォルトを変更できます。

LOGICAL*1 ©

1 バイトの論理データ型 LOGICAL*1BYTE と同義で、以下の値のいずれかをとることができます。

値については 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*2 は 2 バイトの境界に割り当てられます。

LOGICAL*4 ©

論理データ型 LOGICAL*4 は、論理値 .TRUE. または .FLASE. をとります。値は LOGICAL について定義されている値と同じです。

LOGICAL*4 は 4 バイトを占めます。

LOGICAL*4 は 4 バイト境界に割り当てられます。

LOGICAL*8 ©

論理データ型 LOGICAL*8 は、論理値 .TRUE. または .FLASE. をとります。値は LOGICAL データ型について定義されているものと同じです。

LOGICAL*8 は 8 バイトを占めます。

LOGICAL*8 は 8 バイト境界に割り当てられます。

REAL

実数データは実数の近似値です。実数データ型 REAL は通常、REAL*4 と同義で、実数データを表現します。

サイズを指定していない REAL 項目のデフォルトのサイズは通常 4 バイトです。REAL は 4 バイト境界に割り当てられます。しかし、特殊なオプションを指定してコンパイルすれば、これらのデフォルトを変更できます。

REAL の要素は、符号ビット、8 ビットの指数部、23 ビットの小数部で構成されます。f77 での REAL の要素は IEEE 規格に準拠します。

REAL*4 ©

データ型 REAL*4REAL と同義ですが、コンパイラオプションに関係なく、サイズは常に 4 バイトです。

REAL*8 (倍精度実数)©

データ型 REAL*8DOUBLE PRECISION と同義ですが、コンパイラオプションに関係なく、サイズは常に 8 バイトです。

REAL*16 (4 倍精度実数)©

(SPARC のみ) データ型 REAL*16 は 4 倍精度の実数です。

REAL*16 項目のサイズは 16 バイトです。

REAL*16 の要素は、符号ビット、15 ビットの指数部、112 ビットの小数部で構成されます。f77 での REAL*16 の要素は、拡張された精度では IEEE 規格に準拠します。

データ型のサイズと整列条件

記憶領域と整列条件は、常にバイト単位で規定されます。1 バイトに収まる値は、バイト単位で整列されます。

それぞれの型のサイズと整列条件は、コンパイラオプションの指定とプラットフォーム、さらに変数の宣言方法によって異なります。COMMON ブロックの最大整列条件は、4 バイト境界になります。

デフォルトのデータの整列条件や記憶領域の割り当ては、-aligncommon-f
-dalign-dbl_align_all-dbl-xmemalign-r8-i2-xtypemap などのオプションを指定してコンパイルすることにより、変更することができます。このマニュアルでデフォルトについて説明するときは、これらのオプションは指定されていないものと想定します。

個々のコンパイラオプションの詳細については、『Fortran ユーザーズガイド』を参照してください。

次の表に、デフォルトのサイズと整列条件についてまとめています。ただし、それ以外の型やオプションに関する項目は無視しています。

表 2-1   デフォルトのデータサイズと整列条件 (バイト単位) 


デフォルトの
整列条件
COMMON の
整列条件
Fortran 77 のデータ型 サイズ SPARC x86 SPARC x86
BYTE X 1 1 1 1 1
CHARACTER X 1 1 1 1 1
CHARACTER*n X n 1 1 1 1
COMPLEX X 8 4 4 4 4
COMPLEX*8 X 8 4 4 4 4
DOUBLE COMPLEX X 16 8 4 4 4
COMPLEX*16 X 16 8 4 4 4
COMPLEX*32 X 32 8/16 -- 4 --
DOUBLE PRECISION X 8 8 4 4 4
REAL X 4 4 4 4 4
REAL*4 X 4 4 4 4 4
REAL*8 X 8 8 4 4 4
REAL*16 X 16 8/16 -- 4 --
INTEGER X 4 4 4 4 4
INTEGER*2 X 2 2 2 2 2
INTEGER*4 X 4 4 4 4 4
INTEGER*8 X 8 8 4 4 4
LOGICAL X 4 4 4 4 4
LOGICAL*1 X 1 1 1 1 1
LOGICAL*2 X 2 2 2 2 2
LOGICAL*4 X 4 4 4 4 4
LOGICAL*8 X 8 8 4 4 4


次の点に注意してください。

オプション -i2-r8、または -dbl を指定してコンパイルすると、明示的なサイズ指定なしで出力される特定のデータ宣言のデフォルトが変更されます。

表 2-2   -i2-r8-dbl によって変更されるデータのデフォルト
デフォルトの型 -i2 を使用 -r8 または -dbl を使用
INTEGER INTEGER*2 INTEGER*8
LOGICAL LOGICAL*2 LOGICAL*8
REAL REAL*4 REAL*8
DOUBLE REAL*8 REAL*16
COMPLEX COMPLEX*8 COMPLEX*16
DOUBLE COMPLEX COMPLEX*16 COMPLEX*32


-i2-r8 を同時に使用しないでください。同時に使用した場合、予期しない結果が出ることがあります。REAL*16COMPLEX*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 オプションは以下のとおりです。

-dbl は、-xtypemap=real:64,double:128,integer:64 と同じ
-r8 は、-xtypemap=real:64,double:128,integer:mixed と同じ

-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

これらはデフォルトの REALDOUBLE を両方とも 8 バイトに割り当てるため、-r8-dbl よりも実用的です。

INTEGERLOGICAL は同等に処理され、COMPLEX は 2 つの REAL 値として割り当てられます。また、DOUBLE COMPLEXDOUBLE と同じ方法で割り当てられます。

オプション -f または -dalign (SPARCのみ) を指定すると、8 バイト、16 バイト、32 バイトのデータは、すべて 8 バイト境界に割り当てられます。オプション
-dbl_align_all を指定すると、すべてのデータが 8 バイト境界に割り当てられます。これらのオプションに依存するプログラムは、移植性に欠けることがあります。

コンパイラオプションの詳細については、『Fortran ユーザーズガイド』を参照してください。

定数

定数とはプログラム単位を通して値が変化しないデータです。定数を表現する文字列の形式によりその定数の値とデータの型が決まります。(PARAMETER 文で定義される名前付き定数の場合は、名前によってデータ型が決まります。)

一般的な定数には次の 3 つがあります。

算術定数や論理定数に含まれる空白文字は定数の値に影響しません。文字定数に含まれる空白文字は定数の値に影響します。

算術定数には以下のものがあります。

型のある定数 型なしの定数
複素定数 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.f 
	write(*,*) 'a', '', 'b' 
	stop 
	end 
demo% f77 NulChr.f 
NulChr.f: 
 MAIN: 
demo% a.out 
ab 
demo% 

ただし、空文字定数を文字変数に入れると、この変数には空白が含まれ長さは最小で 1 バイトになります。

以下の例は空文字列の長さを示しています。

demo% cat NulVar.f 
	character*1 x / 'a' /, y / '' /, z / 'c' / 
	write(*,*) x, y, z 
	write(*,*) len( y ) 
	end 
demo% f77 NulVar.f 
NulVar.f: 
 MAIN: 
demo% a.out 
a c 
  1 
demo% 

エスケープシーケンス ©

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 進数字列の前にプラス符号 (省略可能) またはマイナス符号が付いたものです。

制限事項

以下に整定数の例を示します。

-2147483648 
-2147483649 			無効 − 小さすぎる、エラーメッセージ
-10 
0 
+199 
29002 
2.71828 		 	INTEGER ではない − 10 進小数点は使えない
1E6				INTEGER ではない − E は使えない
29,002 				無効 − コンマは使えない、エラーメッセージ
2147483647 
2147483648 			無効 − 大きすぎる、エラーメッセージ

代替 8 進表記 ©

整定数の指定には次のような代替 8 進表記を使用することもできます。整数の数字列の前に二重引用符 (") を付け、-xl オプションを指定してコンパイルしてください。このように表記された整定数は 8 進定数です。型は INTEGER です。
次の 2 つの文は等価です。

	JCOUNT = ICOUNT + "703 
	JCOUNT = 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+12 
E-3 
E6

実定数

実定数は次のいずれかの形式をとります。

実指数部は 10 のべき乗で示されます。実定数の値はこの 10 のべき乗と E の前にある定数との積です。

実定数の例を示します。

-32. 
-32.18 
1.6E-9 
7E3 
1.6E12 
$1.0E2.0 			無効  -- $ は使えない、エラーメッセージ
82				REAL ではない  --  10 進小数点か指数が必要
29,002.0 			無効  --  コンマは使えない、 エラーメッセージ
1.6E39 	         		無効  --  大きすぎる、マシンの無限大が使用される
1.6E-39 			無効  --  小さすぎる、いくらか精度が失われる

以下の制限事項があります。

REAL*8 (倍精度実) 定数

倍精度実定数は実際の数の近似値であり、正数、負数、ゼロのいずれかの値をとります。符号がない場合、その定数は負ではないとみなされます。倍精度実定数は倍精度指数部と省略できる小数点を含みます。倍精度定数 REAL*8 は 8 バイトの記憶領域を使用します。REAL*8 表記は規格外です。©

倍精度指数部

倍精度指数部は、文字 D、プラス符号 (省略可能) またはマイナス符号、整数の順で構成されます。

倍精度指数部は 10 のべき乗で示されます。倍精度定数の値はこの 10 のべき乗と D の前にある定数との積です。形式と解釈は、E の代わりに D が使用されることを除いて、実指数部の場合と同じです。

以下に倍精度定数の例を示します。

1.6D-9 
7D3 
$1.0D2.0 			無効  --  $ は使えない、エラーメッセージ 
82				DOUBLE PRECISION ではない  -- 10 進小数点が指数が必要
29,002.0D0 			無効  --  コンマは使えない、 エラーメッセージ
1.8D308 			無効  --  大きすぎる、マシンの無限大が使用される
1.0D-324 			無効  --  小さすぎる、いくらか精度が失われる 

制限事項は次のとおりです。

REAL*16 (4 倍精度実) 定数

(SPARC のみ) 4 倍精度定数は基本実定数または整定数の後ろに 4 倍精度指数部が付いたものです。 「実定数」を参照してください。 ©

4 倍精度指数部は、文字 Q、プラス符号 (省略可能) またはマイナス符号、整数の順で構成されます。

4 倍精度定数は、正数、負数、ゼロのいずれかの値をとります。符号がない場合、その定数は負ではないとみなされます。

以下に 4 倍精度定数の例を示します

1.6Q-9 
7Q3 
3.3Q-4932 
1.1Q+4932 
$1.0Q2.0 			無効  --  $ は使えない、エラーメッセージ 
82 		        	quad ではない -- 指数が必要
29,002.0Q0 			無効  -- コンマは使えない、 エラーメッセージ
1.6Q5000 			無効  -- 大きすぎる、マシンの無限大が使用される
1.6Q-5000 			無効  -- 小さすぎる、いくつか精度が失われる 

形式と解釈は、E の代わりに Q が使用されることを除いて、実定数の場合と同じです。

以下の制限事項があります。

型なし定数 (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, N4 
	DATA N1 /B'0011111'/, N2/O'37'/, N3/X'1f'/, N4/Z'1f'/ 
	WRITE ( *, 1 ) N1, N2, N3, N4, P1 
1	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/, JCOUNT
	REAL*4  TEMP
	M = ICOUNT + B'0001000'
	JCOUNT = ICOUNT + O'777' 
	TEMP = X'FFF99A' 
	WRITE(*,*) M, JCOUNT, TEMP
	END

この例では B'0001000'O'777'INTEGER*4 と定義され、X'FFF99A'REAL*4 と定義されています。実数に対して IEEE 形式の浮動小数点を使用すれば、アーキテクチャが異なっても与えられたビットパターンから生成される値は同じになります。

上記の文は以下のように扱われます。

	M = ICOUNT + 8
	JCOUNT = ICOUNT + 511 
	TEMP = 2.35076E-38 

制御文字

制御文字は次の方法で入力できます。CHAR 関数は規格内ですが、次の方法は規格外です。

例:型なし定数での制御文字

	CHARACTER BELL, ETX / X'03' /
	PARAMETER ( BELL = X'07' )

型なし定数の代替表記

Fortran 77 の他のバージョンとの互換性のため、8 進と 16 進表記には以下の代替表記を使用することができます。この代替表記は 2 進数には無効です。また、DATA 文または PARAMETER 文の中では使用できません。

8 進表記の場合、8 進数字の列をアポストロフィで囲み、その後ろに文字 O を付けます。

例:型なし定数の 8 進代替表記

	'37'O 
	 37'O		無効  -- 最初のアポストロフィがない 
	'37'		数値でない  --  O の文字がない 
	'397'O		無効  -- 無効な数字

16 進表記の場合、16 進数字の列をアポストロフィで囲み、その後ろに文字 X を付けます。

例:型なし定数の 16 進

	'ab'X 
	3fff'X 
	'1f'X 
	'1fX		無効  -- 後ろに続くアポストロフィがない 
	'3f'		数値でない  -- X がない 
	'3g7'X		無効  -- 無効な数 g  

代替表記

2 進、8 進および 16 進定数には、次の規則と制限事項があります。

ホレリス定数 ©

ホレリス定数は、符号なしのゼロ以外の整定数、文字 H、印刷可能文字列の順で構成されます。整定数はスペースとタブも含めて印刷可能文字列中の文字数を指定します。

ホレリス定数は各文字 1 バイトずつの記憶領域を占めます。

ホレリス定数は 2 バイト境界に割り当てられます。

Fortran 77 規格にはこの旧式のホレリス表記はありませんが、古いプログラムとの互換性を維持するためにホレリス機能を装備することをお勧めします。

ホレリスデータを文字列定数の代わりに使用することができます。また、ホレリスデータを IF 文の条件に使用したり、DATA 文や代入文中の変数 (文字変数以外) を初期化するのにも使用できますが、このような使用法は勧められませんし、すべて規格外です。ホレリスデータは型なし定数です。

以下に型なし定数の例を示します。

	CHARACTER C*1, CODE*2 
	INTEGER TAG*2 
	DATA TAG / 2Hok / 
	CODE = 2Hno 
	IF ( C .EQ. 1HZ ) CALL PUNT

ホレリス定数には、次の規則と制限事項があります。

ホレリス定数または変数の長さが変数のデータ型より長い場合は、文字の右側が切り捨てられます。

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 バイトの整定数を指定、値 = 12
12.012_16 	        16 バイトの実定数を指定、値 = 12.012
1.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 ] ... )

ここで、

[ dl:] du

ここで、

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) 

下限が 1 以外の配列の例を次に示します。

	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 つ以上の次元または上下限が整変数の式として指定された局所配列 © です。その整変数は、それ自身が仮引数または共通ブロック内の変数になります。

整合配列は、通常の DIMENSION 文、または型宣言文で宣言できます。f77 では整合配列は RECORD 文でも宣言できます。ただし、その RECORD 文が構造体宣言ブロックの中にはないとします。

次に整合配列の例を示します。

	SUBROUTINE POPUP ( A, B, N ) 
	COMMON / DEFS / M, L
	REAL A(3:5, L, M:N), B(N+1:2*N) !仮引数の配列
	REAL C(N+1,2*N) !局所配列

制限事項は以下のとおりです。

配列がルーチンに対して局所指定される場合は、そのルーチンの入り口でメモリーが割り当てられ、呼び出し元への戻りで割り当てが解除されます。©

大きさ引き継ぎ配列

大きさ引き継ぎ配列とは仮引数として指定された配列であり、かつ、最後の次元の上限がアスタリスクで指定された配列です。

大きさ引き継ぎ配列は、通常の DIMENSION 文、COMMON 文、または型宣言文で宣言できます。

f77 の拡張機能では、以下のことが認められています。©

最後の次元の上限がアスタリスクで指定された大きさ引き継ぎ配列の例を次に示します。

	SUBROUTINE PULLDOWN ( A, B, C ) 
	INTEGER A(5, *), B(*), C(0:1, 2:*) 

大きさ引き継ぎ配列は入出力並びの中では指定できません。

添字なしの配列名

添字なしの配列名はその配列全体を示し、以下の文の中で指定できます。

EQUIVALENCE 文では、添字なしの配列名はその配列の最初の要素を示します。

配列の添字

配列要素名は添字で修飾された配列名です。

添字の形式

添字は括弧で囲まれた添字式の並びです。配列の各次元に対して 1 つの添字式を指定しなければなりません。

添字の形式は次のとおりです。

( s [, s] ... )

ここで s は添字式です。括弧も添字の一部です。

たとえば、次のような宣言子で 2 × 3 の配列を宣言しているとします。

	REAL M(2,3) 

上記について、次のようにすれば、その配列の特定の要素に値を代入することができます。

	M(1,2) = 0.0 

上記の文は、配列 M の行 1、列 2 の要素に 0.0 を代入しています。

添字式

添字式には以下の特性と制限事項があります。

上記の例では V の 4 番目の要素がゼロに設定されます。

32 ビット環境では、添字式が INTEGER*4 の範囲を越えることはできません。添字式が範囲内 (-2147483648, 2147483647) にない場合、結果は予測できません。64 ビット環境用としてコンパイルする場合は、INTEGER*8 の添字式を使用することができます。

配列の順序付け

配列要素はイメージ的には通常、最初の添字を行番号、2 番目の添字を列番号として並べられます。これは伝統的な数学の nxm 行列の表記に対応します。

a1,1 a1,2 a1,3 ... a1,m
a2,1 a2,2 ...
a2,m
... ... ai,j ... ai,m
an,1 an,2 ...
an,m


要素 ai,j は、ij 列にあります。

次に例を示します。

	INTEGER*4 A(3,2) 

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 個以上の文字です。部分列とは、文字変数、文字配列要素、または構造体の記録の文字欄の中の連続した部分のことです。

部分列名は次の 2 つの形式のどちらかで表されます。

v( [ e1 ] : [ e2 ] )

a( s [, s] ... ) ( [ e1 ] : [ e2 ] )

上記の形式中の各記号の意味は次のとおりです。

v
文字変数名
a (s [, s] ... ) 
文字配列要素名
e1
部分列の左端の文字の位置
e2
部分列の右端の文字の位置


e1 e2 は整数式です。32 ビット環境では、整数式が INTEGER*4 の範囲を越えることはできません。整数式が範囲内 (-2147483648, 2147483647) にない場合、結果は予測できません。64 ビット環境用としてコンパイルする場合は、部分列の文字位置を示す式を INTEGER*8 の範囲内で指定することができます。

次の例は、文字変数名 SI 番目の文字を最初の文字とし、L 番目の文字を最後の文字とする文字列です。

	S(I:L) 

上記の例の部分列の文字数は (L-I+1) です。

次の例は、配列要素 A(J,K)M 番目の文字を最初の文字とし、N 番目の文字を最後の文字とする文字列です。

	A(J,K)(M:N) 

上記の例の部分列の文字数は (N-M+1) です。

部分列の規則と制限事項は次のとおりです。

以下に部分列の例を示します。行 2、列 3 の要素の値は e23 です。

demo% cat sub.f 
	character 		v*8 / 'abcdefgh' /, 
& 		m(2,3)*3 / 'e11', 'e21', 
& 		'e12', 'e22', 
& 		'e13', 'e23' / 
	print *, v(3:5) 
	print *, v(1:) 
	print *, v(:8) 
	print *, v(:) 
	print *, m(1,1) 
	print *, m(2,1) 
	print *, m(1,2) 
	print *, m(2,2) 
	print *, m(1,3) 
	print *, m(2,3) 
	print *, m(1,3)(2:3) 
	end 
demo% f77 sub.f 
sub.f: 
 MAIN: 
demo% a.out 
 cde 
 abcdefgh 
 abcdefgh 
 abcdefgh 
 e11 
 e21 
 e12 
 e22 
 e13 
 e23 
 13 
demo% 

構造体

構造体は配列を一般化したものです。©

配列は同じ型の要素の集まりですが、構造体は必ずしも同じ型ではない要素の集まりです。

配列の要素は数値の添字を使用することにより引用されますが、構造体の要素は要素 (または欄) 名を使用することにより引用されます。

構造体宣言では、記録を構成する欄の名前、型、サイズ、および順序を指定して記録の形式を定義します。構造体が定義されて名前が付けられると、以下で説明するようにその構造体を RECORD 文で使用することができます。構造体宣言の構文を以下に示します。

構造体宣言

構造体宣言の構文は以下のとおりです。

STRUCTURE [/構造体名/] [欄の並び]
欄宣言
[欄宣言]
. . .
[欄宣言]
END STRUCTURE
構造体名
構造体の名前
欄の並び
指定された構造体の欄の並び
欄宣言
記録内の欄を定義する欄宣言の定義は次項を参照


 

欄宣言

欄宣言は以下のいずれかです。

次に STRUCTURE 宣言の例を示します。

	STRUCTURE /PRODUCT/ 
	INTEGER*4 ID 
	CHARACTER*16 NAME 
	CHARACTER*8 MODEL 
	REAL*4 COST 
	REAL*4 PRICE 
	END STRUCTURE 

上記の例では、PRODUCT という名前の構造体を5つの欄 ID、NAME、MODEL、COST および PRICE で構成するように定義しています。欄の並びの例は 「構造体の中の構造体」を参照してください。

構造体の規則と制限事項

以下の点に注意してください。

欄の規則と制限事項

型宣言のある欄は通常の Fortran 77 の型宣言文と同じ構文を使用し、f77 のすべての型が使用できます。以下の規則と制限事項に従います。

構造体宣言での欄のオフセット n は、1 つ前にある欄のオフセットにその前欄の長さを加算した値です。整列条件を満たすための調整が行われた場合は、さらにその分が補正されます。記憶領域割り当ての要約については、「データの表現」を参照してください。

記録宣言

RECORD 文は、変数が指定された構造体の記録であることを宣言するか、あるいは配列が指定された構造体の記録の配列であることを宣言します。

RECORD 文の構文は以下のとおりです。

RECORD [/構造体名/ ]記録の並び
[,/構造体名/ 記録の並び]
...
[,/構造体名/ 記録の並び]
構造体名
あらかじめ宣言されている構造体の名前
記録の並び
変数、配列、または、形状が指定された配列の、コンマで区切られた並び


前の STRUCTURE 文の例を用いた RECORD の例を次に示します。

	RECORD /PRODUCT/ CURRENT, PRIOR, NEXT, LINE(10)

3 つの変数 CURRENT、PRIOR および NEXT はそれぞれ PRODUCT 構造体を持つ記録で、LINE はその記録が 10 個集まった配列です。

記録について次の規則と制限事項に注意してください。

記録と欄の引用

記録全体または記録内の個々の欄を引用することができます。また、構造体は入れ子可能なので欄自身を構造体にすることができます。したがって、欄内の欄を引用したり、そのまた内側の欄を引用することができます。

記録と欄の引用の構文は以下のとおりです。

記録名[.欄名] ... [.欄名]
記録名
あらかじめ定義されている記録変数の名前
欄名
直前 (左側) に指定されている記録の中にある欄の名前


前記の 2 つの例の構造体と記録を用いた引用例を以下に示します。

	...
	RECORD /PRODUCT/ CURRENT, PRIOR, NEXT, LINE(10) 
	... 
	CURRENT = NEXT 
	LINE(1) = CURRENT 
	WRITE ( 9 ) CURRENT 
	NEXT.ID = 82

上記の例では、

構造体と記録の宣言、および記録と欄への代入の例を以下に示します。

demo% cat str1.f 
* str1.f 単純構造体 
	STRUCTURE / S / 
	INTEGER*4 I 
	REAL*4 R 
	END STRUCTURE 
	RECORD / S / R1, R2 
	R1.I = 82 
	R1.R = 2.7182818 
	R2 = R1 
	WRITE ( *, * ) R2.I, R2.R 
	STOP 
	END 
demo% f77 -silent str1.f 
demo% a.out 
82 2.718280 
demo% 

部分構造体の宣言

構造体の中の欄をさらに構造体にすることができます。このような欄を部分構造体と呼びます。部分構造体は次のどちらかの方法で宣言します。

構造体の中の記録

入れ子にした構造体宣言とは、構造体宣言または共用体宣言の中に含まれている構造体宣言のことです。以前に定義された記録を構造体宣言の中で使用することができます。

あらかじめ定義された記録 PRODUCT を使用して構造体 SALE を定義する例を以下に示します。

	STRUCTURE /SALE/ 
	CHARACTER*32  BUYER 
	INTEGER*2  QUANTITY 
	RECORD     /PRODUCT/  ITEM 
	END STRUCTURE

上記の例では、構造体 SALEBUYER、QUANTITY および ITEM の 3 つの欄を含んでいます。ITEM は構造体 /PRODUCT/ をもつ記録です。

構造体の中の構造体

宣言の中で宣言を入れ子にすることができます。

/PRODUCT/ があらかじめ宣言されていない場合、SALE の宣言の中で宣言することができます。以下に例を示します。

	STRUCTURE /SALE/ 
	CHARACTER*32  BUYER 
	INTEGER*2  QUANTITY 
	STRUCTURE /PRODUCT/ ITEM 
	INTEGER*4  ID 
	CHARACTER*16  NAME 
	CHARACTER*8  MODEL 
	REAL*4  COST 
	REAL*4  PRICE 
	END STRUCTURE 
	END STRUCTURE 

この例でも、前記の例と同じく、構造体 SALE は 3 つの欄 BUYER、QUANTITY および ITEM を含みます。欄 ITEM は「構造体の宣言」で定義された欄の並び (この場合は要素数が 1 個の並び) の例です。

それぞれの構造体のサイズと複雑さにより、与えられた状況に最も適した部分構造体宣言の方式を決めます。

部分構造体内の欄の引用

部分構造体内の欄を引用することができます。

部分構造体 (前記の例の PRODUCT および SALE が現行プログラム単位内で定義されているとする) の欄を引用する例を次に示します。

	... 
	RECORD /SALE/ JAPAN 
	... 
	N = JAPAN.QUANTITY 
	I = JAPAN.ITEM.ID 
	... 

部分構造体の規則と制限事項

次のことに注意してください。

UNION と MAP

共用体宣言は実行時に記憶領域を共有する欄のグループを定義します。

構文

共用体宣言の構文は以下のとおりです。

	UNION 
	マップ宣言
	マップ宣言
	[マップ宣言] 
	... 
	[マップ宣言] 
	END UNION

マップ宣言の構文は以下のとおりです。

	MAP 
	欄宣言 
	[欄宣言] 
	... 
	[欄宣言] 
	END MAP

マップ内の欄

マップ宣言の中の各欄宣言は以下のうちのいずれかです。

マップ宣言は、共用体の中に代替の欄グループを定義します。実行中のある時点では、どちらか一方のマップが共有の記憶場所に関連付けられています。マップ内の欄を引用すると、それ以前に記憶場所に関連付けられていたマップの欄グループは未定義になり、新しく引用された欄が属するマップの欄グループが記憶場所を引き継ぎます。共用体が使用するメモリー量はその共用体の中の最大のマップが使用するメモリー量です。

以下の例では、構造体 /STUDENT/NAME、CLASS および MAJOR か、もしくは NAME、CLASS、CREDITS および GRAD_DATE を含むように宣言しています。

	STRUCTURE /STUDENT/ 
	CHARACTER*32  NAME 
	INTEGER*2  CLASS 
	UNION 
		MAP 
			CHARACTER*16 MAJOR 
		END MAP 
		MAP 
			INTEGER*2  CREDITS 
			CHARACTER*8  GRAD_DATE 
		END MAP 
	END UNION 
	END STRUCTURE

変数 PERSON が上記の例の構造体 /STUDENT/ を持つように定義した場合、PERSON·MAJOR は最初のマップの欄を引用し、PERSON.CREDITS は 2 番目のマップの欄を引用します。2 番目のマップの欄の変数が初期化された後でプログラムが変数 PERSON.MAJOR を引用した場合、最初のマップが有効になり、2 番目のマップの各変数は未定義になります。

ポインタ

POINTER 文は変数とポインタの対を設定します。©
各ポインタには対になる変数のアドレスが含まれています。

構文の規則

POINTER 文の構文は次のとおりです。

	POINTER ( p1, v1 ) [, ( p2, v2 ) ... ] 

ここで、

ポインタ基底付き変数とは、POINTER 文で指定されるポインタと対になっている変数です。ポインタ基底付き変数は、通常は単に基底付き変数または指示先と呼ばれます。ポインタはアドレスを含んでいる整変数です。(POINTER 文で指定する変数名は、コンパイラでは VOLATILE と見なされます)

次に単純な POINTER 文の例を示します。

	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*12 
	DATA 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 Z
	REAL X, Y
	POINTER ( P1, X ), ( P2, Y ), ( P3, Z ) 
	... 
	P1 = MALLOC ( 10000 ) 
	... 

上記の例では、MALLOC() が 10,000 バイトのメモリーを割り当て、そのメモリーブロックのアドレスとポインタ P1 を関連付けています。

FREE() サブルーチンによる記憶領域の割り当て解除

サブルーチン FREE() は先に MALLOC() により割り当てられた記憶領域を解放します。
FREE() に与える引数は、MALLOC() により返されたポインタでなければなりません。これはプログラマが FREE() に与える必要があります。記憶領域はメモリーマネージャに戻され、メモリーマネージャはプログラマがその記憶領域を使用できないようにします。

FREE による割り当て解除の例を以下に示します。

	POINTER ( P1, X ), ( P2, Y ), ( P3, Z ) 
	... 
	P1 = MALLOC ( 10000 ) 
	... 
	CALL FREE ( P1 ) 
	... 

上記の例では、MALLOC() が 10,000 バイトのメモリーを割り当て、そのメモリーがポインタ P1 に関連付けられます。その後、FREE() がその同じ 10,000 バイトをメモリーマネージャに戻しています。

特記事項

malloc()loc()free() を使用してポインタとメモリー割り当てを操作する場合は、以下の点に特に注意してください。

最適化とポインタ

ポインタを使用すると、大域的オプティマイザの処理の前提範囲が限定されます。次の 2 つの場合を比較してください。

したがって、オプティマイザは、サブルーチンまたは関数の呼び出しにおいて引数として渡される変数が、他の呼び出しにより変更される可能性を仮定しなければなりません。このようなポインタの無制約な使用は、ポインタを使用しない大部分のプログラムに対しても最適化のレベルを低下させることになります。

一般的なガイドライン

ポインタが最適化を行うには、 2 つの選択があります。

2 番目の選択には更に選択肢があります。ポインタをルーチンに局所的に使用し、それは最適化せず、計算を行うルーチンのみを最適化します。呼出しルーチンを別々のファイルに入れることにより、あるルーチンは最適化し、あるものは最適化しないということができます。

例:-03 または -04 でも比較的安全なコーディング

	REAL A, B, V(100,100) 	 このプログラム単位は、 
	POINTER ( P, V )      	 アドレスを取得して渡す以外に
	P = MALLOC(10000)     	 P では何も行わない
	... 
	CALL CALC ( P, A )
	...
	END

 
	SUBROUTINE CALC ( ARRAY, X )
	...
	RETURN
	END

レベル -04CALC のみを最適化したい場合は、CALC 内ではポインタを使用しないでください。

注意事項

次のようなコーディングの仕方では、レベル -03 または -04 での最適化で問題が生じる可能性があります。

例: -03 または -04 で問題を発生させるコード

	COMMON A, B, C
	POINTER ( P, V ) 
	P = LOC(A) + 4 			  最適化を行うと、ここで問題が起こる可能性がある
	... 

コンパイラは、P を通した引用により A が変更されると仮定しますが、B が変更されることは仮定しません。この仮定により誤ったコードが生成される可能性があります。


サン・マイクロシステムズ株式会社
Copyright information. All rights reserved.
ホーム   |   目次   |   前ページへ   |   次ページへ   |   索引