科学計算の場合、行列式や1次元配列、2次元配列が頻繁に出てくる…と思われる。
Fortran の場合、あまり可変配列を使わずに、あらかじめメモリ領域を確保する固定配列を使う…ってそうしていたのだが、最近はどうなのだろう。可変にするとメモリの確保に時間がかかってスピードに問題がでるので、固定長さの配列のほうが有利。
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 | module structmodule implicit none ! struct define type F3D double precision :: x,y,z end type F3D contains ! one array integer function sum1( v, count ) integer :: v(10) integer :: i, total integer :: count total = 0 do i=1,count print *, 'in sum1: ', i, v(i) total = total + v(i) end do sum1 = total end function sum1 ! 二次元配列を渡す integer function sum2( v, cnti, cntj ) integer :: v(3,4) integer :: cnti, cntj integer :: i,j integer :: total total = 0 do i=1,cnti do j=1,cntj print *,i,j,v(i,j) total = total + v(i,j) end do end do sum2 = total end function sum2 end module structmodule |
引き数で配列の数を渡しているが、内部で固定にしかならないので、この場合はあまり意味がない。
最大長をチェックしてオーバーフローにならないように気を付けるとか。
1 2 3 4 5 6 | extern "C" { // 1次元配列 int STRUCTMODULE_mp_SUM1( int ary[], int *count ); // 2次元配列 int STRUCTMODULE_mp_SUM2( int ary[][3], int *cnti, int *cntj ); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | int v1[] = {1,2,3,4,5,6,7,8,9,10}; int count = 10; int sum1 = STRUCTMODULE_mp_SUM1( v1, &count ); cout << "ans:" << sum1 << endl; int v2[4][3] = { {1,2,3}, {2,3,4}, {3,4,5}, {4,5,6}, }; int cnti = 3, cntj = 4; int sum2 = STRUCTMODULE_mp_SUM2( v2, &cnti, &cntj ); cout << "ans:" << sum2 << endl; |
注意しないといけないのは、Fortranは「1」始まりで、C++は「0」始まりということ。なので、Fortranで「3」番目にアクセスをすると、C++では添え字の「2」にアクセスする(0始まりなので、3番目の要素になる)。配列そのものを扱う場合には気にならないが、index を渡す場合には注意が必要。
Fortranのほうを0始まりにできるオプションもあるらしいのだが、元のソースに合わせるとすると標準的な1始まりの配列を扱うほうがよかろう。
あと、2次元配列の場合は、次元が逆のように見える。これは、Fortranのほうにあわせて作る。