前記事(配列(1)-基本操作)では、プログラムの最初に配列の上限と下限を宣言しました。
プログラムの途中で、配列の上限と下限を決めたい場合は、動的割付けという手続きを行います。
この記事ではこの動的割付けの手続きについて説明します。
記事の最後にサンプルプログラムを掲載しています。
動的割付けの手続き
動的割付けを行いたい配列は、以下のようにallocatable属性を指定して宣言します。配列1と配列2は配列名です。
配列の型, allocatable :: 配列1(:)___! 1次元配列
配列の型, allocatable :: 配列2(:,:)__! 2次元配列
動的割付けは以下のようにallocate文を用いて行います。
allocate( 配列1(下限:上限) )__________! 1次元配列
allocate( 配列2(下限:上限,下限:上限) )__! 2次元配列
プログラム終了時にメモリの解放は自動的に行われますが、明示的に解放する場合は、以下のようにdeallocate文を用います。
deallocate( 配列1 )
自動配列と動的割付け配列
副プログラム内で以下のように配列を宣言した場合、この配列は副プログラム開始時に自動的にメモリに割付けられ、終了時も自動的に解放されます。このような配列を自動配列といいます。
real(8) :: x(1:n)
自動配列はスタック領域を利用する場合があり、その場合は、動的割付け配列よりも割付けが高速になります。しかし、スタック領域にはサイズ制限があり、OSやコンパイラなどの環境によってサイズが異なります。
環境変数を設定することで、スタック領域のサイズは変更が可能ですが、環境依存性が小さいプログラムを作成したい場合は、副プログラム内の配列は自動配列ではなく、動的割付け配列を利用することが推奨されます。
サンプルプログラム
サンプルプログラムを下記します。2-9行目はメインルーチン、12-23行目は自動配列を使用するサブルーチン、26-28行目は動的割付け配列を使用するサブルーチンです。
内容は1~nまでの数値の二乗の計算を行って、結果をx(i)に格納し、これを出力するというものです。
以下のFortranプログラムをコピペし、****.f90の名前で保存して下さい(****の部分は適当でいいです)。コピペが面倒な場合は、こちらからダウンロードして下さい(右クリックメニューから保存)。→ sample11.f90
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | !---------------------------- メインルーチン program sample11 implicit none integer :: n_auto, n_alloc n_auto = 1000 ! 自動配列のサイズ n_alloc = 1000 ! 動的割付け配列のサイズ call sample11_auto(n_auto) ! サブルーチン呼び出し(自動配列) call sample11_alloc(n_alloc) ! サブルーチン呼び出し(動的割付け配列) end program sample11 !---------------------------- サブルーチン(自動配列) subroutine sample11_auto(n_auto) implicit none integer, intent(in) :: n_auto integer :: i real(8) :: x(1:n_auto) x = 0.0d0 do i = 1, n_auto x(i) = dble(i) * dble(i) if (mod(i,n_auto/10) == 0) & ! この条件を満たす場合に出力 & write(*,'(i10,1x,e15.4)') i, x(i) end do end subroutine sample11_auto !---------------------------- サブルーチン(動的割付け配列) subroutine sample11_alloc(n_alloc) implicit none integer, intent(in) :: n_alloc integer :: i real(8), allocatable :: x(:) allocate( x(1:n_alloc) ) ; x = 0.0d0 ! 動的割付けと初期化 do i = 1, n_alloc x(i) = dble(i) * dble(i) if (mod(i,n_alloc/10) == 0) & ! この条件を満たす場合に出力 & write(*,'(i10,1x,e15.4)') i, x(i) end do deallocate( x ) ! メモリ解放 end subroutine sample11_alloc |
使い方は、前記事と同様に、****.f90を以下の****.batにドラッグ&ドロップするだけです。
64bit用 → comp_exe_64.bat
32bit用 → comp_exe_32.bat
こんな画面が出たでしょうか?出ていれば正常終了です。5-6行目の配列サイズを変えて、色々試してみて下さい。
→ 次の記事へ(OpenMPによる並列化)
← 前の記事へ(モジュール)
目次(Fortran90)