Fortran 2003 はFortranの標準です。この本は現代のFortranに焦点を当て、Fortran 77やそれ以前の標準の古い機能には触れません。

Hello World

編集

以下はFortranでのHello Worldプログラムです。

program hello
   implicit none
   write (*,*) "Hello, world."
end program hello

"implicit none" 文は、すべての変数を宣言するようにプログラマーに強制し、良いスタイルと考えられています。Fortranには整数、文字、実数、複素数、論理型のデータ型があります。以下のプログラムはそれらの使用法を示しています。

program data_types
   implicit none
   integer :: i
   real :: x
   logical :: tf
   complex :: z
   i = 3
   x = 3.0
   z = (3.0,3.0)
   tf = .true.
   write (*,*) "i =",i," x =",x," z =",z," tf = ",tf
end program data_types
出力
i = 3 x = 3. z = (3.,3.) tf = T

算術演算子

編集

Fortranには、加算(+), 減算(-), 除算(/), 乗算(*), および冪乗(**)の算術演算子があります。次のプログラムの出力は次のとおりです。

program xx
   implicit none
   write (*,*) 2+3,2-3,2/3,4*3,2**3
end program xx
出力
5 -1 0 12 8

配列

編集

Fortran 90以降のバージョンでは、配列の強力な機能があります。次のプログラムは配列のいくつかの機能を示しています。デフォルトでは、配列要素はCC++のように0ではなく1から番号付けされます。

program xarray
   ! 配列コンストラクターと組み込み関数をデモする
   implicit none
   integer, parameter :: n = 3
   integer :: vec(n)
   vec = (/9,4,1/)          ! vec(1)を9、vec(2)を4、vec(3)を1に設定する
   write (*,*) "vec = ",vec ! vecの各要素を出力する
   write (*,*) "vec(1) = ",vec(1),", vec(3) =",vec(3) ! 1番目と3番目の要素を出力する
   write (*,*) "size(vec), sum(vec), product(vec) = ", &
                size(vec), sum(vec), product(vec)
   write (*,*) "minval(vec), maxval(vec) = ",minval(vec),maxval(vec)
   vec = vec + 2            ! vecの各要素に2を加える
   write (*,*) "vec = ",vec ! vecの各要素を出力する
   vec = vec**2             ! vecの各要素を2乗する
   write (*,*) "vec = ",vec ! vecの各要素を出力する
end program xarray
出力
vec = 9 4 1
vec(1) = 9 , vec(3) = 1
size(vec), sum(vec), product(vec) = 3 14 36
minval(vec), maxval(vec) = 1 9
vec = 11 6 3
vec = 121 36 9

ループ

編集

Fortranでは、反復のためにdoループを使用します。たとえば、次のプログラムは次の出力を生成します。

program xloop
   implicit none
   integer :: i
   do i=1,3
      write (*,*) i,i**2
   end do
   write (*,*) "i=",i
   do i=1,4,2
      write (*,*) i
   end do
   write (*,*) "i=",i
end program xloop
出力
1 1
2 4
3 9
i= 4
1
3
i= 5

最初のループでは、変数iは1から3までの値を取り、ステップサイズは1です。2番目のループではステップサイズが2です。ループを完了した後、iの値はループを終了する前の最後の値にステップサイズを加えたものです。

比較演算子

編集

Fortranには、<、<=、/=、==、>=、>などの比較演算子があります。/= は「等しくない」を意味し、他の演算子は通常の意味を持ちます。次のプログラムは次の出力を生成します。

program xcompare
   implicit none
   write (*,*) 1<0,1<=0,1==0,1/=0,1>=0,1>0
end program xcompare
出力
F F F T T T

カウンター変数のないDOループを持つことができます。この場合、EXIT文がループを抜けるために必要になります。以下のプログラムで示されているように。

program xfibonacci
   ! max_fibまでのフィボナッチ数を出力する
   implicit none
   integer, parameter :: max_fib = 10
   integer            :: i,fib,fib1,fib2
   i    = 0
   fib  = 0
   fib1 = 0
   fib2 = 0
   write (*,*) "Fibonacci numbers <= ",max_fib
   do
      if (fib > max_fib) exit
      write (*,*) fib
      i = i + 1
      if (i > 1) then
         fib  = fib1 + fib2
      else
         fib = 1
      end if
      fib2 = fib1
      fib1 = fib
   end do
end program xfibonacci

max_fibをパラメーターとして宣言すると、その値はプログラムの残りの部分で変更できなくなります。

ネストされたループ

編集

ループをネストすることができます。次のプログラムで示されているように。

program xnest
   implicit none
   integer :: i,j
   do i=1,3
      do j=1,2
         write (*,*) "i,j=",i,j
      end do
   end do
end program xnest
出力
i,j= 1 1
i,j= 1 2
i,j= 2 1
i,j= 2 2
i,j= 3 1
i,j= 3 2

関数と戻り値

編集

関数は、0個以上の引数に依存して値を返すために使用できます。以下のコードは、華氏度から摂氏度への変換を行う関数を示しています。

module convert_mod
   implicit none
contains
   function cels_from_fahr(degrees_fahr) result(degrees_cels)
   real, intent(in) :: degrees_fahr
   real             :: degrees_cels
   degrees_cels = (degrees_fahr-32)/1.8
   end function cels_from_fahr
end module convert_mod

program xtemperature
   use convert_mod, only: cels_from_fahr
   real    :: deg
   integer :: i
   write (*,"(2a10)") "degrees_F","degrees_C"
   do i=12,100,20
      deg = real(i)
      write (*,"(2f10.1)") deg,cels_from_fahr(deg)
   end do
end program xtemperature
出力
degrees_F degrees_C
12.0 -11.1
32.0 0.0
52.0 11.1
72.0 22.2
92.0 33.3

サブルーチン

編集

サブルーチンは式で使用することはできず、call文で呼び出されます。以下のプログラムで示されているように、同じ出力を生成します。

module convert_mod
   implicit none
contains
   subroutine cels_from_fahr(degrees_fahr,degrees_cels)
   real, intent(in)  :: degrees_fahr
   real, intent(out) :: degrees_cels
   degrees_cels = (degrees_fahr-32)/1.8
   end subroutine cels_from_fahr
end module convert_mod

program xtemperature
   use convert_mod, only: cels_from_fahr
   real    :: deg_f,deg_c
   integer :: i
   write (*,"(2a10)") "degrees_F","degrees_C"
   do i=12,100,20
      deg_f = real(i)
      call cels_from_fahr(deg_f,deg_c)
      write (*,"(2f10.1)") deg_f,deg_c
   end do
end program xtemperature