4 定数と変数
4.1 Fortran のデータ型
Fortran には主に以下のような組込み型が用意されています。
型 | 記述方法 |
整数型 | integer |
実数型 | real |
倍精度実数型 | double precision |
複素数型 | complex |
倍精度複素数型 | complex(kind(0d0)) |
論理型 | logical |
文字型 | character |
4.2 変数
変数は宣言してから利用します。 変数名は英字で始まる任意の英数字とアンダースコア "_" の組み合わせで、最大 31 文字(Fortran 90/95 の標準規格)まで指定可能です。【変数の宣言例】 integer a real b, sub_total complex(kind(0d0)) dt1
文字列は括弧を用いて長さを指定することができます。 指定を行わなかった場合には長さは 1 となります。
【文字列変数の宣言例】 character a ! 長さ 1 文字の変数 character(len=4) b ! 長さ 4 文字の変数 character(4) c ! このように "len=" を省略することも可能 character*4 d ! このような記述方法もある character e*4, f*5 ! このような書き方でも良い
ここで a は長さが 1 の文字を表し、b と c と d と e は長さ 4 の文字列を表し、f は長さ 5 の文字列を表します。
補足情報
本テキストに示された方法以外にも、良く見られる型の記述方法があります。
それぞれの記述方法について、なぜ推奨されていないのか、理由を述べたいと思います。
型 | 推奨 | 記述 | 説明 |
単精度実数 | 〇 | real | 単精度はこの記述方法が推奨されます |
単精度実数 | × | real(4) | 種別番号 4 の意味がコンパイラによって異なります(4 バイトを意味するとは限らない) |
単精度実数 | × | real*4 | Fortran 標準に準拠していません |
倍精度実数 | 〇 | double precision | 倍精度はこの記述方法が推奨されます |
倍精度実数 | × | real(8) | 種別番号 8 の意味がコンパイラによって異なります(8 バイトを意味するとは限らない) |
倍精度実数 | × | real*8 | Fortran 標準に準拠していません |
単精度複素数 | 〇 | complex | 単精度複素数はこの記述方法が推奨されます |
単精度複素数 | × | complex(4) | コンパイラにより種別番号 4 の意味が異なります |
単精度複素数 | × | complex*8 | Fortran 標準に準拠していません |
倍精度複素数 | 〇 | complex(kind(0d0)) | 倍精度複素数はこの記述方法が推奨されます |
倍精度複素数 | × | complex(8) | 種別番号 8 の意味がコンパイラによって異なります |
倍精度複素数 | × | complex*16 | Fortran 標準に準拠していません |
倍精度複素数 | × | double complex | Fortran 標準に準拠していません |
変数は初期値を指定することが可能です。 初期値の指定は変数名に続き =初期値 とします。 また初期値を指定する場合には型名と変数名の間に ::(コロンが2つ)が必要です。
【変数の宣言時に初期値を指定する例】 integer :: a = 99 real :: b = 5.2 complex :: c = (1.2,3.4)
変数には属性を付加することが可能です。属性の指定は型名につづきカンマを指定してその後ろに属性を指定します。
複数の属性を指定したい場合には更にカンマで続けます。
また属性を指定する場合にも初期値を指定する場合と同様、型、属性並びに続き ::(コロンが2つ)、そして変数名の順に記述します。
よく利用される属性には以下が含まれます。
属性 | 意味 | 用例 |
dimension | 変数の形状(寸法と次元)を指定します | integer,dimension(10,3) :: a |
parameter | 変数が定数である旨を指定します | real,parameter :: pi = 3.14 |
allocatable | 変数が割付け(動的な領域確保)可能であることを指定します | real,allocatable :: a(:) |
※ parameter 属性を指定した場合には、上記にも示される通り、必ず初期値を指定する必要があります。
【誤った変数の宣言例】 integer a = 10 ! 初期値を指定する場合には :: が必要です real,dimension(4) b ! 属性(ここでは dimension を指定した場合には :: が必要です) real,parameter :: c ! parameter 属性を指定した場合には初期値を指定する必要があります
以下に変数宣言を含んだ(正しい)コード例を示します。
例1 program main real r ! 実数の変数 r を宣言 real,parameter :: pi = 3.14 ! 定数 pi を定義 :: が必要な例 r = 5.0 print *, r*r*pi end program main 例2 program main character(3) a ! :: は無くても良い character(len=4) :: b = "ABCD" ! 初期化する場合は :: が必要 a = "xyz" print *, a print *, b end program main
parameter 属性はあってもなくてもプログラムは動作しますが定数を記述する際にはプログラマの意図を明示するためにもその利用が推奨されます。
以下に parameter 属性の使用意義を表すサンプルを示します。 (parameter 属性を指定すると下記のプログラムは p = 1.0 を指定した行でエラーとなりプログラマの意図に反した誤りを見つけてくれます。)
program parameter_attr implicit none real r real :: p=3.14 ! parameter 属性を指定しない場合の宣言 !! !! 例えばここに何百行ものコードがあったとする !! p = 1.0 ! ここでプログラマの意図に反して p を他の目的に使ってしまっている !! !! そしてここにも何百行ものコードがあったとする !! print *, "Enter radius:" read *, r print *, r, "x", r, "x 3.14 =", r*r*p end program parameter_attr (意図に反した)実行例: Enter radius: 1.0 1.0000000 x 1.0000000 x 3.14 = 1.0000000
[ parameter-attr.f90 ] - parameter 属性の使用意義を示すサンプル
4.3 data 文による初期値の設定について
変数に初期値を与えるには data 文を用いることも可能です。 data 文は宣言文の後に記述される非実行文の一つです。data 初期化項目並び/初期値表現並び/ [[,] 初期化項目並び/初期値表現並び/] ... 例) integer i, j real x, y, z data i,j/1,2/ data x,y,z/1.,2.,3./ 上記2行の data 文を以下のようにまとめて書くことも可能 data i,j,x,y,z/1,2,1.,2.,3./ もしくは以下のような記述でも同意 data i,j/1,2/ x,y,z/1.,2.,3./
data 文の初期値表現並びには反復回数の指定を行うことが可能です。 反復の指定はアスタリスク(*)を用いて以下のように行います。
反復回数*値 例) integer i, j, k data i,j,k/3*0/ ! i と j と k に初期値 0 を設定する
data 文は配列に初期値を与える場合にも利用可能です。 以下は配列の各要素に初期値を与える例です。
integer a(8), b(4) data a/1,2,3,4,5,6,7,8/ data b/4*100/ ! b のすべての成分に初期値 100 を与える例
4.4 implicit none について
バグを防ぐためにも implicit none の記述が強く推奨されています。 これは Fortran の古くからの機能である「暗黙の型宣言」を使わないことを明示的に示す宣言です。各プログラム単位の最初に implicit none を指定します。 use 文がある場合には use 文の前ではなく後に指定をします。
下記の例は implicit none を宣言したおかげで 4 行目で iconter(正しくは icounter)としてしまった誤りがコンパイル時に検出されます。
implicit none を指定しないと、エラーにはならずコンパイルが行えてしまい、思わぬバグの原因となってしまいます。
[
error-detection.f90
] - implicit none の使用意義を示す、誤りを含むサンプル
program error_detection implicit none integer :: icounter = 0 iconter = icounter + 1 ! implicit none を宣言したおかげで、このスペルミスがエラーとなる! print *, icounter end program error_detection
4.5 定数表現
4.5.1 整数
整数は以下のように数字を組み合わせて記述します。 負を表す "-" もしくは正を表す "+" を最初に記述することも可能です。 符号を省略した場合には正の数とみなされます。【正しい整数表現の例】 12 +12345 -1234 0 【誤った整数表現の例】 1.2 12,000
4.5.2 実数
単精度実数は以下のように記述します。【単精度実数表現の例】 1.23 1.23e0 -1.23e3 1.23e-3
上記は上から順番にそれぞれ 1.23, 1.23, -1230, 0.00123 を表します。
倍精度を表す場合には "e" の部分を "d" とします。 上記の4つの単精度表現に対応する倍精度表現は以下の通りです。
【倍精度実数表現の例】 1.23d0 1.23d0 -1.23d3 1.23d-3
※ 倍精度実数は単精度実数と区別されるので注意が必要です。 例えば、以下の例のように倍精度変数 a に単精度実数 1.23 を指定すると思わぬ結果(例えば、1.2300000190734863)となります。 出力結果はコンパイラにより異なりますが 1.23000000 とはなりません。
【誤った記述例 - 倍精度と単精度の混同】 double precision a a = 1.23 print *, a 出力例: 1.2300000190734863
単精度が求められるところでは単精度、倍精度が求められるところでは倍精度を指定するように注意して下さい。
4.5.3 複素数
複素数 a+bi を表すには (a,b) とします。 a と b はそれぞれ実数を指定します。 この際に単精度複素数では単精度表現を、そして倍精度複素数では倍精度表現を用います。【単精度複素数の例】 (1.23, -1.4) (1.2e-3, 2.0) 【倍精度複素数の例】 (1.23d0, -1.4d0) (1.2d-3, 2.0d0)
4.5.4 文字
文字表現はアポストロフィ ' もしくは引用符 " で括って表現します。 アポストロフィで括った場合にアポストロフィーを2つ続けると一つのアポストロフィを意味します。 同様に引用符で括った場合に引用符を2つ続けて記述すると一つの引用符を意味します。【文字表現の例】 'ABC' ! ABC "ABC" ! ABC 'A "plus" B' ! A "plus" B "He's" ! He's 'He''s' ! He's "AB""CD" ! AB"CD
4.5.5 論理定数
論理定数は真であれば .true. 偽であれば .false. で表現します。【論理定数の例】 .true. .false. .TRUE. ! 大文字小文字は関係ありません .FALSE. ! 大文字小文字は関係ありません
4.6 構造型
Fortran では integer や real などの組込み型の他にこれらを組み合わせた新しい型(構造型と呼ばれます)を定義して利用することができます。型の定義は例えば以下のように行います。
type student character(32) :: name integer :: age end type student
定義された型を用いるには下記のように宣言をします。
type(student) :: a
構造型の各成分(ここでは name と age)へのアクセスは % を用いて下記に示されるように記述します。
a%name = "Sato" a%age = 20
構造型の定数表現は下記の例のように型の名前に続き括弧で括られた形で各成分を列記して行います。
a = student("Sato",20)
構造型はその成分に別の構造型を含めることができます。 下記に例を示します。
【構造型を含む構造型の定義】 type point real :: x, y end type point type line type(point) :: p1, p2 end type line 【コード例】 program type_example implicit none ! point 型を定義 type point real :: x, y end type point ! line 型を定義(point 型を利用している) type line type(point) :: p1, p2 end type line ! line 型の変数 m を宣言 type(line) m m = line( point(0.0,0.0), point(1.0,1.0) ) print *, m end program type_example
前へ 上へ 次へ