配列(2)-動的割付け

前記事(配列(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


sample11


こんな画面が出たでしょうか?出ていれば正常終了です。5-6行目の配列サイズを変えて、色々試してみて下さい。


→ 次の記事へ(OpenMPによる並列化)
← 前の記事へ(モジュール)
目次(Fortran90)

スポンサーリンク

コメントをどうぞ

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です