文法・書式・使用方法
作成者自身が忘れやすいもののメモ. つまり,Fortran の文法などに関する包括的な記述ではない. 初学者には不向きである.
- 参考文献リスト: Fortran に関する包括的な記述が知りたければ,このあたりをきっかけに自分で探してください
- F90 個人的記入ルール: 私個人のルール.基本は気象庁/気象研の 標準コーディングルール にあわせた(つもり)
文字型データに関する組込関数
文字列処理の組込関数リスト
下の表にまとめる.I は整数型,C は文字型,L は論理型の引数.
組込み関数 | 処理内容 | 解説 |
---|---|---|
ADJUSTL(C) | 左詰め | 先頭の空白を詰める(左詰め) |
ADJUSTR(C) | 右詰め | 後部の空白を詰める(左詰め) |
CHAR(I) | 整数式を文字に変換 | ASCII コードに対応した文字を返す |
ICHAR(C) | 文字をASCIIコードに変換 | |
INDEX(C1, C2) | 検索 | 文字型データC1内に文字型データC2文字列を探す.存在すれば開始位置,存在しなければ0 を返す |
TRIM(C) | 文字の後部の空白を詰める | 文字列Cの後部の空白を削除 |
LEN_TRIM(C) | 文字数(後部空白を除外) | |
LEN(C) | 文字数 | 文字列Cの全文字数を整数型で返す |
LGE(C1, C2) | 大小比較 ≥ | C1 >= C2 なら true |
LGT(C1, C2) | 大小比較 > | |
LLE(C1, C2) | 大小比較 ≤ | |
LLT(C1, C2) | 大小比較 < | |
REPEAT(C, I) | 文字列の連結(繰り返し回数指定) | REPEAT('hoge', 3) で hogehogehoge を返す |
SCAN(C1, C2, L) | 文字列C1中の文字列C2の位置(文字数) | 第3引数(論理型)の有無により挙動が異なる(詳細は補足情報を参照) |
補足情報
SCAN 関数
- ケース (i): SCAN ('FORTRAN', 'TR') は値 3 を返す(第2引数の文字列のひとつ前の文字数を返す)
- ケース (ii): SCAN ('FORTRAN', 'TR', BACK = .TRUE.) は値 5 を返す(第2引数の最後の文字が存在する文字数を返す)
- ケース (iii): SCAN ('FORTRAN', 'BCD') は値 0 を返す(一致する文字列がないので,ゼロを返す)
具体的な使用例:
- フルパスで書いたファイル名の,ディレクトリ部分を除くファイル名部分だけを取り出す. Linux, MacOS などのUN*X系 OS での basename コマンドに相当.
PROGRAM char_trim_test IMPLICIT NONE INTEGER, PARAMETER :: max_len = 255 CHARACTER(LEN=max_len) :: input_path, fullpath_name CHARACTER(LEN=max_len) :: in_file, out_file INTEGER start_char, end_char INTEGER ilength1, ilength2 input_path = '/data/hoge/hogehoge/' in_file = 'test.txt' fullpath_name = TRIM(input_path)//TRIM(in_file) ilength1 = LEN(fullpath_name) ilength2 = LEN_TRIM(fullpath_name) WRITE(*, '(2i5, " : ", a)') ilength1, ilength2, TRIM(fullpath_name) start_char = SCAN(fullpath_name, '/', .TRUE.) end_char = LEN_TRIM(fullpath_name) out_file = fullpath_name(start_char+1:end_char) WRITE(*, '(2x, a,2x, a)') 'Cut-off filename :', TRIM(out_file) END PROGRAM char_trim_test
数値に関する組込み関数
自分がよく忘れるもののみ列挙:
整数化に関する組込み関数
組込み関数名 | 用途 |
---|---|
NINT(a) | 四捨五入整数化 |
FLOOR(a) | 引数の値以下の最大の整数値を返す (ガウス記号) |
CEILING(a) | 引数の値以上で最小の整数値を返す |
NINT() は,大気汚染データ処理(環境基準の判定,2%除外値の算出)でも使用. See 大気汚染関連情報 - 大気環境基準
- 使用例
PROGRAM main IMPLICIT NONE INTEGER, PARAMETER :: nv = 8 REAL, DIMENSION(nv) :: a REAL :: r1, r2, r3 INTEGER :: d1, d2, d3 INTEGER :: iv a(1) = 0.34 a(2) = -0.34 a(3) = -0.52 a(4) = -3.23 a(5) = 3.80 a(6) = 0.80 a(7) = -0.80 a(8) = -9.80 WRITE(*, '(a4, 6a8)') & "No.", "value", "nint", "floor", "ceiling", "aint", "anint" do iv = 1, nv d1 = nint( a(iv) ) ! 四捨五入した整数値.整数型 d2 = floor( a(iv) ) ! 引数の値以下の最大の整数値を返す (ガウス記号) d3 = ceiling( a(iv) ) ! 引数の値以上で最小の整数値を返す r1 = aint( a(iv) ) ! 切捨てによる整数値,ただし型は real で返す r2 = anint( a(iv) ) ! 四捨五入した整数値,ただし型は real で返す WRITE(*, '(i4, f8.2, 3i8, 2f8.1)') & iv, a(iv), d1, d2, d3, r1, r2 enddo ! iv END PROGRAM main
ビット処理
組込み関数名 | 処理内容 |
---|---|
iand( m, n ) | 引数のビット単位の論理積を計算する (使用例: EASE grid snow cover and sea ice サンプル読みだしスクリプト,Fortran code 付き) |
ior( m, n ) | 引数のビット単位の論理和を計算する |
ieor( m, n ) | 引数のビット単位の排他的論理和を計算する |
ishft( m, k ) | 循環桁上げなしで論理シフトする (k>0 のときは左、k<0 のときは右へ) |
ishftc( m, k, ic ) | 循環シフト: m の、右から ic ビットを左へ k ビット循環シフトする |
ibits( m, i, len) | ビットの切り出し: i ビット目から始まる len ビット分を m から切り出す |
ibset( m, i ) | ビットをセットする: ビット i が 1 であれば戻り値は m と同じです |
ibclr( m, i ) | ビットをクリアーする: ビット i が 0 であれば戻り値は m と同じです |
btest( m, i ) | ビットのテスト: m の i 番目のビットをテストする。ビットが 1 のときは .true. を返し、ビットが 0 のときは .false. を戻す |
繰り返し処理 (do, while)
do ループの順序(多次元配列使用時)
Fortran では,多次元配列のデータは column major order で メモリ上に格納される. すなわち,a(2, 2) という2行2列の2次元配列のデータは, a(1, 1), a(2, 1), a(1, 2), a(2, 2) という並び順となる.
doループを使って多次元配列にアクセスするとき, 並び順にアクセスする方が高速である. つまり, a(ix, iy) (ix = 1, nx ; iy = 1, ny) というデータでは, iy を変数とした do ループを外側に置き,その中で ix についての do ループにする方が効率的である.
do iy = 1, ny do ix = 1, nx a(ix, iy) = b + c enddo ! ix enddo ! iy
上記が正解.配列数が小さい場合は,順序を入れ替えても人間が実感できる程の差はない. 莫大な量の繰り返しがあると,その差を体感できるだろう.
引数の処理
簡単な例
Fortran 実行ファイルをコマンド化,コマンド引数に入出力ファイル名を指定して実行... という事をやりたい
PROGRAM MAIN INTEGER, PARAMETER :: max_len = 255 ! 255-character INTEGER :: i, num_args CHARACTER(LEN=max_len) :: arg, exec_name CHARACTER(LEN=max_len) :: ifile1, ifile2 ! +++ Get number of arguments num_args = command_argument_count() WRITE(*, '(a, i10)') "No. of arguments = ", num_args ! argument 0: executable filename ! argument 1: 1st argument ! argument 2: 2nd argument i = 0 DO CALL get_command_argument(i, arg) ! Fortran 2003 or later IF (LEN_TRIM(arg) == 0) EXIT arg_selector: SELECT CASE (i) CASE (0) exec_name = TRIM(arg) CASE (1) ifile1 = TRIM(arg) CASE (2) ifile2 = TRIM(arg) END SELECT arg_selector i = i + 1 END DO WRITE(*, '(a)') "exec_name = "//TRIM(exec_name) WRITE(*, '(a)') "ifile1 = "//TRIM(ifile1) WRITE(*, '(a)') "ifile2 = "//TRIM(ifile2) END PROGRAM
下記が実行例. こういう使いかたが出来るようになれば, コマンド引数を利用した「自分専用」実行ファイルを Fortran で自作できる. シェルスクリプトから使用するときも,書式が簡単. これはとても便利.
$ gfortran test.f90 $ ./a.out ~/tmp/hoge1.txt ~/tmp/hoge2.txt No. of arguments = 2 exec_name = ./a.out ifile1 = /home/viper/hayasaki/tmp/hoge1.txt ifile2 = /home/viper/hayasaki/tmp/hoge2.txt
上記プログラムは, ifort (ver. 11.1), gfortran (gcc ver. 4.1.2 20080704 (Red Hat 4.1.2-52)) にて 正常動作することを確認. 他の環境でも,大抵動くだろう.
参考サイト
最初に見つけたのは,玉川さん@岐阜大のページ. さすがだ.
- Sample of Fortran and tcsh (玉川さん@岐阜大)(確認年月日: 2012-10-21)
ファイル操作
inquire 文でいろんなファイル操作が出来そう. size, exist, opened, name, number, など (wrote at 2015-10-03)
- ファイル容量・ファイルサイズの取得(size)
integer :: file_size open(unit=15, file="input_file") inquire(unit=15, size=file_size) write(*, '(a, i12)') "file size = ", file_size
- ファイル名(name),open済みか否か(opened),ユニット番号(number),の照会
character(len=256) :: file_name inquire(unit=11, name=file_name) write(*, '(a)') "file name = "//TRIM(file_name)
- ファイルの存在(exist),open済みか否か(opened),ユニット番号(number),の照会
integer unit_num logical open_stat, exist_stat inquire(file="input_file", opened=open_stat, exist=exist_stat, number=unit_num)