Fortran/変数
はじめに
[編集]プログラミングにおいて変数とは、プログラムが変更できるデータの入れ物です。通常、変数を使用する前には、どのようなデータを格納するかの情報を提供するために、変数を宣言します。しかし、Fortranでは暗黙的に変数を作成することができます。 implicit
の記述がない場合、i
/I
からn
/N
まで(inグループ)で始まる宣言されていない変数や引数はinteger
となり、それ以外の宣言されていない変数や引数はreal
となります。
多くの人は、宣言せずに変数を使うことを悪習と考えています。もし変数の宣言を強制されたいのであれば、まず :implicit none
をコーディングしてください。
一般的な例
[編集]通常の変数の例を以下に示します。
! 定数を宣言し、値を変更できないようにする integer, parameter :: num_days_week = 7 ! i を整数、j を j(1) から j(2) の2つの整数の配列、k を k(0) から k(1) の2つの整数の配列、m を12要素の2次元配列として宣言 integer :: i, j(2), k(0:1), m(3,4) ! c を c(0) から c(3) までの4つの浮動小数点数の配列として宣言 real :: c(0:3) ! word を長さ5の文字列として宣言 character (len=5) :: word ! .TRUE. または .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 ! i を 3*4 = 12 に設定します j = [1, 4] ! j(1) を 1、j(2) を 4 に設定します c = [1.0, 4.0, 5.0, 9.0] ! c(0) を 1.0、c(1) を 4.0、c(2) を 5.0、c(3) を 9.0 に設定します word = 'dog' ! word を "dog" に設定します。変数 word は右側にスペースで埋められます tf = .true. ! tf を 真(True) に設定します
変数は、代入の両サイドに現れることができます。右辺が先に評価され、その値に変数が代入されます。
i = 3 ! i は値 3 を持ちます i = i**i ! i は値 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) ! 数値を倍精度浮動小数点数に変換 print *, real(r), real(d), real(i) ! 数値を単精度浮動小数点数に変換 print *, int(r), int(d), int(i) ! 数値を整数に変換
また、同じことをよりシンプルで古風な形で表現しています。
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 ! 特定の要素を設定する arr(1:2) = [4, 5] ! 範囲を指定して設定する(スライス表記) arr = [4, 5, 6] ! 全体の配列を設定する
初期化
[編集]- 様々な配列変数の初期化方法
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
多次元配列を設定するには、reshape
やshape
コマンドを利用する必要があります。
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]) ! 上記のコマンドと同じ効果 - arr の形状をハードコードする ! arr は以下の行列を表します: ! 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 は以下の行列を表します: ! 1 2 3 ! 4 5 6