PC パソコン

Fortran基本文法|Hello World・変数・計算・入出力・IF・DO・配列

Fortran基本文法|Hello World・変数・計算・入出力・IF・DO・配列

この記事では、Fortranを初めて学ぶ人向けに、もっとも基本的な文法を実際のプログラムを動かしながら解説します。
前の記事でgfortranのインストールが完了していることを前提に、Hello World、変数、データ型、四則演算、入力と出力、IF文、DO文、配列までを順番に学びます。

Fortranのコードでは、行の途中に「!」を書くと、その右側はプログラムとして実行されないコメント(注釈)になります。
この記事では、初学者でもコードの意味を追いやすいように、サンプルコードの中にもコメントを多めに記載しています。

最初のFortranプログラム「Hello World」

まずは、画面に文字を表示するだけの簡単なプログラムを作ります。
次のコードをテキストエディタに入力し、hello.f90という名前で保存してください。

program hello
    ! program hello はプログラムの開始を表します。
    ! hello の部分は、このプログラムにつけた名前です。

    implicit none
    ! 変数を使うときに、必ず自分で宣言するようにします。
    ! 初心者のうちは基本的に書いておくと考えてください。

    print *, "Hello, Fortran!"
    ! print は画面に文字や数値を表示する命令です。
    ! * は標準的な形式で表示するという意味です。
    ! " " で囲まれた部分は文字列としてそのまま表示されます。

end program hello
    ! プログラムの終了です。

保存したら、ターミナルまたはMSYS2 UCRT64で、ファイルを保存したフォルダへ移動し、次のようにコンパイルします。

gfortran hello.f90 -o hello

MacやLinuxでは次のように実行します。

./hello

WindowsのMSYS2では、次のように実行できます。

./hello.exe

次のように表示されれば成功です。

Hello, Fortran!

Fortranプログラムの基本構造

最初のプログラムを簡単に整理すると、基本的には次のような形になります。

program プログラム名

    implicit none

    ! ここに変数の宣言を書く

    ! ここに実際の処理を書く

end program プログラム名

Fortranでは、プログラムの開始と終了を明確に書くことができます。
また、implicit noneは非常に重要です。
Fortranには、古い時代から引き継がれている「変数名によって自動的に型を推測する仕組み」がありますが、初心者にとっては入力ミスに気づきにくくなる原因になります。

そのため、Modern Fortranではimplicit noneを書き、変数を必ず明示的に宣言する書き方を基本にすると分かりやすくなります。

コメントの書き方

Fortranでは「!」から右側がコメントになります。コメントは実行されないため、コードの説明やメモとして利用できます。

! この1行全体がコメントです。

x = 10.0
! x に 10.0 を代入します。

y = x * 2.0    ! 行の途中からコメントを書くこともできます。

学習中は、「この変数は何を表すのか」「この計算は何をしているのか」などをコメントとして残しておくと理解しやすくなります。

変数とは

変数とは、数値や文字などのデータを一時的に保存しておくための名前付きの入れ物です。
例えば、半径を保存する変数をradius、面積を保存する変数をareaとすると、何の値を扱っているのかコードを見ただけで分かりやすくなります。

real :: radius
real :: area

::の左側にはデータの種類、右側には変数名を書きます。

Fortranの主なデータ型

データ型 意味
integer 整数 1、10、-5
real 実数 3.14、25.5、-0.8
character 文字列 Hello、Fortran
logical 真・偽 .true.、.false.

整数 integer

integer :: age
age = 20

integerは、小数部分を持たない整数を保存します。

実数 real

real :: temperature
temperature = 25.5

realは、小数を含む数値を扱うときに使用します。科学技術計算では非常によく使う型です。

文字列 character

character(len=20) :: name
name = "Fortran"

len=20は、最大20文字分の領域を確保するという意味です。

論理値 logical

logical :: passed
passed = .true.

logicalは、「正しい・間違い」「条件を満たす・満たさない」のような2つの状態を表すときに使います。Fortranでは、真を.true.、偽を.false.と書きます。

変数に値を代入する

変数に値を入れることを代入と呼びます。Fortranでは=を使います。

integer :: number
real :: temperature

number = 10
temperature = 23.5

ここでの「=」は、数学の「左右が等しい」という意味よりも、右側の値を左側の変数へ入れるという意味で使われています。

複数の変数をまとめて宣言する

real :: width, height, area
integer :: i, count

同じ型の変数はカンマで区切ってまとめて宣言できます。短いプログラムでは便利ですが、意味が分かりにくい場合は1行ずつ宣言してコメントを付けても構いません。

四則演算

計算 記号
足し算 + a + b
引き算 a – b
掛け算 * a * b
割り算 / a / b
べき乗 ** a ** 2

四則演算の例

program arithmetic
    implicit none

    real :: a, b
    real :: addition
    real :: subtraction
    real :: multiplication
    real :: division

    ! a と b に値を代入します。
    a = 10.0
    b = 4.0

    ! 足し算
    addition = a + b

    ! 引き算
    subtraction = a - b

    ! 掛け算
    multiplication = a * b

    ! 割り算
    division = a / b

    print *, "a + b =", addition
    print *, "a - b =", subtraction
    print *, "a * b =", multiplication
    print *, "a / b =", division

end program arithmetic

整数同士の割り算には注意する

Fortranを初めて学ぶときに注意したいのが、整数同士の割り算です。

integer :: a, b
real :: answer

a = 5
b = 2

answer = a / b

この場合、a / b は整数同士の計算として先に処理されるため、期待した2.5にはなりません。
小数を含む計算を行いたい場合は、少なくとも一方をreal型として扱います。

real :: a, b, answer

a = 5.0
b = 2.0

answer = a / b

print *, answer

この場合は2.5になります。

計算の優先順位

Fortranでも、掛け算や割り算は足し算や引き算より先に計算されます。

answer = 2.0 + 3.0 * 4.0

この場合は14.0です。計算順序を変えたい場合は丸括弧を使います。

answer = (2.0 + 3.0) * 4.0

この場合は20.0になります。

数学関数を使う

関数 意味
sqrt(x) 平方根
sin(x) 正弦
cos(x) 余弦
tan(x) 正接
exp(x) 指数関数
log(x) 自然対数
abs(x) 絶対値
program square_root
    implicit none

    real :: x
    real :: answer

    x = 16.0

    ! sqrt は平方根を求める関数です。
    answer = sqrt(x)

    print *, "square root =", answer

end program square_root

PRINTで画面に表示する

printは、文字や変数の値を画面に表示するときに使います。

program output_example
    implicit none

    integer :: number

    number = 100

    print *, "Hello"
    print *, number
    print *, "number =", number

end program output_example

文字列と変数をカンマで区切れば、一緒に表示できます。

READでキーボードから入力する

ユーザーが入力した値を受け取るには、readを使用します。

program input_example
    implicit none

    real :: number

    ! 入力を求める案内を表示します。
    print *, "数値を入力してください。"

    ! キーボードから入力された値を number に保存します。
    read *, number

    ! 入力された値を表示します。
    print *, "入力された値 =", number

end program input_example

実行すると、プログラムはreadの位置で入力を待ちます。数値を入力してEnterキーを押すと、その値が変数numberへ保存されます。

入力された2つの数を足してみる

program add_two_numbers
    implicit none

    real :: a
    real :: b
    real :: answer

    print *, "1つ目の数を入力してください。"
    read *, a

    print *, "2つ目の数を入力してください。"
    read *, b

    ! 入力された2つの数を足します。
    answer = a + b

    print *, "合計 =", answer

end program add_two_numbers

WRITEとは

writeも出力に使う命令です。printよりも細かな指定ができ、画面だけでなくファイルへの出力にも利用されます。

write(*,*) "Hello, Fortran!"

最初の*は標準出力、2つ目の*は標準的な表示形式を使うことを表します。
初学者の段階では、画面への簡単な表示はprint、細かな出力制御やファイル出力ではwriteも使う、と考えれば十分です。

IF文で条件によって処理を変える

例えば、入力された点数が60点以上なら「合格」、60点未満なら「不合格」と表示できます。

program score_check
    implicit none

    integer :: score

    print *, "点数を入力してください。"
    read *, score

    ! score が 60 以上かどうかを確認します。
    if (score >= 60) then

        ! 条件を満たした場合に実行されます。
        print *, "合格です。"

    else

        ! 条件を満たさなかった場合に実行されます。
        print *, "不合格です。"

    end if

end program score_check

比較演算子

記号 意味
== 等しい
/= 等しくない
> より大きい
< より小さい
>= 以上
<= 以下

代入に使う=と、比較に使う==は意味が違うので注意してください。

ELSE IFで条件を増やす

program grade_check
    implicit none

    integer :: score

    print *, "点数を入力してください。"
    read *, score

    if (score >= 80) then
        print *, "評価A"
    else if (score >= 60) then
        print *, "評価B"
    else
        print *, "評価C"
    end if

end program grade_check

条件は上から順番に確認されます。そのため、より厳しい条件を先に書くと整理しやすくなります。

複数の条件を組み合わせる

演算子 意味
.and. 両方の条件を満たす
.or. どちらか一方を満たす
.not. 条件を反転する
if (age >= 18 .and. age <= 65) then
    print *, "条件の範囲内です。"
end if

DO文で繰り返す

例えば、1から5まで表示する場合は次のように書けます。

program do_example
    implicit none

    integer :: i

    ! i を 1 から 5 まで1ずつ増やしながら繰り返します。
    do i = 1, 5
        print *, i
    end do

end program do_example

iは、現在何回目の繰り返しかを表すためによく使われる変数です。

増加量を指定する

do i = 0, 10, 2
    print *, i
end do

この場合は2ずつ増えるため、0、2、4、6、8、10と表示されます。

逆向きに繰り返す

do i = 5, 1, -1
    print *, i
end do

5、4、3、2、1の順に表示されます。

DO文で合計を求める

program sum_example
    implicit none

    integer :: i
    integer :: total

    ! 合計を保存する変数を最初に0にします。
    total = 0

    do i = 1, 100
        ! 現在の total に i を足し、結果を再び total に保存します。
        total = total + i
    end do

    print *, "合計 =", total

end program sum_example

total = total + iは、「現在のtotalにiを足した値を、新しいtotalとして保存する」という意味です。

条件を満たすまで繰り返すDO WHILE

program while_example
    implicit none

    integer :: number

    number = 1

    ! number が5以下である間、繰り返します。
    do while (number <= 5)
        print *, number
        number = number + 1
    end do

end program while_example

配列とは

配列とは、同じ種類のデータを複数まとめて保存するための仕組みです。
例えば5人分の点数を保存するとき、変数を5個作る代わりに1つの配列へまとめられます。

integer :: score(5)

これで、5個の整数をまとめて保存できる配列scoreを作れます。

配列に値を入れる

program array_example
    implicit none

    integer :: score(5)

    ! 配列の各場所へ値を代入します。
    score(1) = 80
    score(2) = 75
    score(3) = 90
    score(4) = 68
    score(5) = 85

    print *, score(1)
    print *, score(2)
    print *, score(3)
    print *, score(4)
    print *, score(5)

end program array_example

Fortranの配列は、何も指定しなければ1番から始まります
C、Java、Pythonなどでは0番から始まることが多いため、他の言語を知っている人は違いに注意してください。

配列をまとめて初期化する

integer :: score(5)

score = [80, 75, 90, 68, 85]

配列の要素数と、指定する値の数を合わせます。

DO文と配列を組み合わせる

program array_loop
    implicit none

    integer :: score(5)
    integer :: i

    score = [80, 75, 90, 68, 85]

    ! score(1) ~ score(5) を順番に表示します。
    do i = 1, 5
        print *, "score(", i, ") =", score(i)
    end do

end program array_loop

配列の合計と平均を求める

program average_score
    implicit none

    integer :: score(5)
    integer :: i
    integer :: total
    real :: average

    score = [80, 75, 90, 68, 85]
    total = 0

    ! 5個の点数を順番に合計します。
    do i = 1, 5
        total = total + score(i)
    end do

    ! real()を使って整数を実数へ変換してから割ります。
    average = real(total) / 5.0

    print *, "合計 =", total
    print *, "平均 =", average

end program average_score

配列同士をまとめて計算する

Fortranの大きな特徴の一つが、配列全体をまとめて計算できることです。

program array_calculation
    implicit none

    real :: a(3)
    real :: b(3)
    real :: c(3)

    a = [1.0, 2.0, 3.0]
    b = [10.0, 20.0, 30.0]

    ! 配列の同じ位置同士を加算します。
    c = a + b

    print *, c

end program array_calculation

結果として11、22、33に相当する値が配列cへ保存されます。このように大量の数値をまとめて扱いやすいことが、Fortranが科学技術計算で長く使われている理由の一つです。

2次元配列

配列は1列だけでなく、行と列を持つ2次元配列として作成できます。行列などを扱う場合に利用します。

real :: matrix(3, 3)

matrix(1, 1) = 1.0
matrix(1, 2) = 2.0
matrix(1, 3) = 3.0

2次元配列や行列計算については、数値計算の記事でさらに詳しく扱うことができます。

よくある初学者のミス

implicit noneを書かず、変数名を打ち間違える

初学者はimplicit noneを書く習慣を付けると、変数名の入力ミスを見つけやすくなります。

整数同士を割り算する

小数の答えが必要な場合は、real型を使うか、real()で型を変換して計算します。

= と == を間違える

x = 10

if (x == 10) then
    print *, "x は10です。"
end if

=は値の代入、==は値が等しいか比較するときに使用します。

IF文やDO文を閉じ忘れる

if (x > 0) then
    print *, "正の数です。"
end if

do i = 1, 10
    print *, i
end do

ここまでで作れる簡単なプログラム

  • 2つの数値を入力して四則演算する
  • 三角形や円の面積を計算する
  • 摂氏と華氏を変換する
  • 点数から合否を判定する
  • 複数の点数の平均を求める
  • 1から指定した数までの合計を求める
  • 九九を表示する
  • 配列に保存した測定値を順番に処理する

基本文法をまとめたサンプル

最後に、5個の測定値を入力し、平均値を求め、平均値が50以上かどうかを判定するプログラムを紹介します。

program basic_summary
    implicit none

    ! 5個の実数を保存する配列です。
    real :: data(5)

    ! 合計値と平均値を保存する変数です。
    real :: total
    real :: average

    ! DO文で使用する整数変数です。
    integer :: i

    ! 合計を計算する前に0へ初期化します。
    total = 0.0

    ! 5個の値を順番に入力します。
    do i = 1, 5
        print *, i, "個目の値を入力してください。"
        read *, data(i)
    end do

    ! 配列に保存された5個の値を合計します。
    do i = 1, 5
        total = total + data(i)
    end do

    ! 平均値を求めます。
    average = total / 5.0

    print *, "合計 =", total
    print *, "平均 =", average

    ! 平均値によって表示内容を変更します。
    if (average >= 50.0) then
        print *, "平均値は50以上です。"
    else
        print *, "平均値は50未満です。"
    end if

end program basic_summary

このプログラムには、変数、real型、integer型、配列、READ、PRINT、DO文、四則演算、IF文がすべて含まれています。
最初はコードをそのまま入力して動かし、数値や条件を変更して実行結果がどう変わるか試してみると、各文法の役割を理解しやすくなります。

まとめ

この記事では、Fortranの基本文法として、Hello World、コメント、変数、データ型、四則演算、READ・PRINT・WRITE、IF文、DO文、配列について解説しました。
この範囲を理解すると、入力した数値を計算したり、条件によって処理を変更したり、複数のデータを繰り返し処理したりする基本的なFortranプログラムを作れるようになります。

次の段階では、関数、サブルーチン、ファイルの読み書きを学ぶことで、より長いプログラムを処理ごとに分割したり、計算結果をファイルへ保存したりできるようになります。