はじめに 編集

プログラミングにおいて変数とは、プログラムが変更できるデータの入れ物です。通常、変数を使用する前には、どのようなデータを格納するかの情報を提供するために、変数を宣言します。しかし、Fortranでは暗黙的に変数を作成することができます。 implicitの記述がない場合、i/Iからn/Nまで(inグループ)で始まる宣言されていない変数や引数はintegerとなり、それ以外の宣言されていない変数や引数はrealとなります。

多くの人は、宣言せずに変数を使うことを悪習と考えています。もし変数の宣言を強制されたいのであれば、まず implicit none をコーディングしてください。

簡単な例
Program Hello
   implicit none
   integer :: a1 = 10, a2 = 34
   Print *, a2
end program
実行結果
          34

行の冒頭で integer と宣言する事で、整数の型の変数を宣言できます。

 2つ以上の変数を宣言したい場合は , で区切って続けて宣言できます。


a1,a2が整数として宣言できているか確認するために、加算をしてみましょう。

加算
Program Hello
   implicit none
   integer :: a1 = 10, a2 = 34
   Print *, a1 + a2
end program
実行結果
          44

10+34 は 44 ですので、たしかにa1(=10)、a2(=34)ともに整数として宣言できている事が分かります。


型だけ宣言する場合

変数の宣言において、型だけ先に宣言しておいて後から数値を代入したい場合は、下記のようになります(下記コードの数値では、動作確認しやすくするため、数値を上記コードから変えてあります)。

初期化せず後から代入
Program Hello
   implicit none
   integer a1
   a1 = 14
   Print *, a1
end program
実行結果
          14

このようにFortranで変数宣言をする際は、一般的に

型名 :: 変数名 = 初期値

あるいは

型名 変数名

のような構文です。

また、C++やC99以降のC言語と異なり、宣言は実行文の後には書けません。

実行文の後に宣言を書いたイリーガルなコード
Program Hello
   implicit none
   integer :: a1 = 42
   Print *, a1
   integer :: a2 = 19
   Print *, a1 + a2
end program
コンパイル結果
gfortran -ffree-form   -O  decl.f   -o decl
decl.f:5:21:

    5 |    integer :: a2 = 19
      |                     1
Error: Unexpected data declaration statement at (1)
decl.f:6:19:

    6 |    Print *, a1 + a2
      |                   1
Error: Symbol 'a2' at (1) has no IMPLICIT type; did you mean 'a1'?
*** Error code 1

Stop.

一般的な例 編集

通常の変数の例を以下に示します。

! Declare a constant, whose value cannot be changed.
integer, parameter :: num_days_week = 7
! Declare i as an integer, j as an array of 2 integers from j(1) to j(2), k as
! an array of 2 integers from '''k(0)''' to k(1), and m as a 2-dimensional
! array of 12 elements.
integer :: i, j(2), k(0:1), m(3,4)
! Declare c as an array of 4 floating point numbers from c(0) to c(3).
real :: c(0:3)
! Declare word as a string of length 5
character (len=5) :: word
! Declare a boolean variable with values .TRUE. or .FALSE.
logical :: tf

以下は、まったく同じことをしていますが、より短く、より古風な形になっています。

INTEGER, PARAMETER :: num_days_week = 7
DIMENSION j(2), k(0:1), m(3,4), c(0:3)
CHARACTER*5 word
LOGICAL tf

メモリのレイアウトを重視する場合は、m(1,1)の後にm(2,1)が続き、m(1,2)は続かないことに注意してください。

変数に値を設定するには、変数を等号の前に置き、等号の後に設定される値を置く。上記の宣言を行うと、以下のような代入が可能です。

i    = 3*4                  ! Set i to 3*4 = 12         
j    = [1, 4]               ! Set j(1) to 1, j(2) to 4
c    = [1.0, 4.0, 5.0, 9.0] ! Set c(0) to 1.0, c(1) to 4.0, c(2) to 5.0, c(3) to 9.0
word = 'dog'                ! Set word = "dog  " . The variable word is padded with spaces on the right
tf   = .true.               ! Set tf to True

変数は、代入の両サイドに現れることができます。右辺が先に評価され、その値に変数が代入されます。

i = 3     ! i has value 3
i = i**i  ! i has value 3**3 = 27

変数はある型から別の型に変換することができますが、C++やJavaのように変数を型付けするのではなく、Fortranでは固有の手続きを使用します。

real          :: r = 1.5
real (kind=8) :: d = 1.5
integer       :: i = 1

print *, dble(r), dble(d), dble(i)   ! Convert number to a double precision
print *, real(r), real(d), real(i)   ! Convert number to a single precision (REAL)
print *, int(r), int(d), int(i)      ! Convert number to an integer

また、同じことをよりシンプルで古風な形で表現しています。

 DOUBLE PRECISION d = 1.5
 r = 1.5
 i = 1
 PRINT *, DBLE(r), DBLE(d), DBLE(i)
 PRINT *, REAL(r), REAL(d), REAL(i)
 PRINT *, INT(r), INT(d), INT(i)

配列 編集

宣言 編集

配列の宣言には2種類の表記法があります。次の例は、integer型で長さ5の配列の表記法を示しています。

integer, dimension (5) :: arr1
integer                :: arr2(5)

多次元配列の場合は、各次元の長さを指定する必要があります。次の例では、5x6の整数行列が長さ(5,6)の2次元配列になっている場合を示しています(ここでも両方の表記をしています)。

integer, dimension (5,6) :: arr1
integer                  :: arr2(5,6)

初期化 編集

配列を実際の値で初期化するには、特定の要素,特定の範囲,あるいは配列全体を設定するという複数の選択肢があります。

integer :: arr(3)

arr(1)   = 4            ! set specific element
arr(1:2) = [4, 5]       ! set a range aka slicing notation
arr      = [4, 5, 6]    ! set whole array
様々な配列変数の初期化方法
Program Init 
  integer::a (5) = [1, 2, 3, 4, 5]   ! 配列構成子の代替形式
  integer::b (5) = (/1, 2, 3, 4, 5/) ! 配列構成子スカラ式
  integer::c (5) = (/(i, i=1, 5)/)   ! 配列構成子DO形反復
  integer::x (5) = 1                 ! 配列要素を全て1に
  Print *, a 
  Print *, b 
  Print *, c 
  Print *, x
  x = a           ! 配列変数に配列変数を代入
  Print *, x
  Print *, x * 2  ! 配列変数xの要素全てに _ * 2
  Print *, 2 ** x ! 配列変数xの要素全てに 2 ** _
end program
           1           2           3           4           5
           1           2           3           4           5
           1           2           3           4           5
           1           1           1           1           1
           1           2           3           4           5
           2           4           6           8          10
           2           4           8          16          32

多次元配列を設定するには、reshapeshapeコマンドを利用する必要があります。

integer :: arr(2,3)

arr = reshape([1,2,3,4,5,6], shape(arr))
! arr = reshape([1,2,3,4,5,6], shape=[2,1])  ! same effect as above command - hardcode the shape of arr

! arr represents matrix:
! 1 3 5
! 2 4 6

Fortranでは列メジャーな順序を採用しているため、上の例ではよくわからない行列ができてしまいます。行メジャーの順序では,次の例のように,どの次元で最初にソートするかを order 引数で指定することができます.

integer :: arr(2,3)

arr = reshape([1,2,3,4,5,6], shape(arr), order=[2,1])

! arr represents matrix:
! 1 2 3
! 4 5 6