- 締切済み
配列サイズを明示せずサブルーチンに渡す方法
プログラムのメインの方で2次元、3次元の高次元配列を設定してそれをサブルーチンに引き渡すことを考えています(しょっちゅうやっていることですが)。 この場合、サブルーチン側に汎用性を持たせるためにできるだけ配列のサイズを自動で渡すようにしたいと思っています(メインが変わるとそれに応じて自動対応)。そうしないとサブルーチンが汎用化せず、ケースバイケース(メイン側の配列のサイズが変わる場合それに応じてコードを書き変えなければならない)に応じなければならず、うっかりミスの間違いもおこりそうです。 配列のサイズを決めないサブルーチンの書き方を教えて頂きたいのですが。 なお、今回は配列はデータとして参照するだけで書き換えることはありません。 言語ですが、”サブルーチン”というだけあってFortranです。(Cのカテゴリだと答えを頂けるかなと思っているのですが。他に適当なところも無いようですが)
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- f272
- ベストアンサー率46% (8533/18270)
こんな感じ? program main use,intrinsic :: iso_fortran_env implicit none integer(int32) :: a(4,3)=reshape([1,2,3,4,5,6,7,8,9,10,11,12], [4,3]) call checkArray(a) contains subroutine checkArray(x) use,intrinsic :: iso_fortran_env implicit none integer(int32) :: x(:,:) print *,"shape =",shape(x) print *,"size =",size(x) print *,"lbound=",lbound(x) print *,"ubound=",ubound(x) print *,x(1,:) print *,x(2,:) print *,x(3,:) print *,x(4,:) end subroutine checkArray end program main
- asciiz
- ベストアンサー率70% (6825/9705)
Cなら構造体、C++なら3次元配列のクラス(オブジェクト)を作る感じでしょうかね。 ●C言語の場合 typedef struct { int x, y, z; float *mem; } ARRAY3D; // ARRAY3D型(構造体)の定義 void init_array(ARRAY3D *ary, int x, int y, int z) { *ary->x = x; // x, y, z、各サイズを記録 *ary->y = y; *ary->z = z; *ary->mem = malloc(x*y*z*sizeof(float)); // 全サイズぶんのメモリ確保 for (int i=0; i<x*y*z; i++) {*ary->mem[i] =0.0f}; // 全要素を (float)0.0 で初期化 } void main(void) { // main()関数から実行が開始されます ARRAY3D a; // ARRAY3D型の a を用意 init_array(&a, 2, 3, 4); // aを2x3x4サイズで初期化 calc_array(a); // a を関数に渡して処理 } ※コンパイラ通してないのでいろいろエラーがあるかもしれません ※mallocのエラーを想定してないとか超いいかげんです、まあサンプルと言うことで maim()でやりたい事はコメントに書いたとおりなのですが、最後に calc_array(a); としたところで、その呼び出された関数の方では、配列のサイズ a->x、a->y、a->z を知ることができ、a->mem アドレスから始まる配列内容を参照することができると言うわけです。 ※init_array関数では、(C言語なので)参照渡しして、malloc(メモリ確保)した値をmain()のa->memに書き込めていますが、それがダメならmain()内でmallocしないといけないかもしれません。 C++だと、class ARRAY3D を定義して、x, y, z, mem をクラスのメンバーとし、コンストラクタに配列サイズの記録とメモリの確保、デストラクタではメモリの解放、そして配列に対する操作をメソッドとして実装していく…みたいになるでしょうか。 そちらの方がスマートだと思います。 私は原始的なFORTRANしか知らないので、最近のFORTRANではオブジェクト的な書き方もできるとか…? C++のclassでサンプル書いた方が良かったのかもしれません(汗
- notnot
- ベストアンサー率47% (4900/10359)
呼び出し元からサイズを引数で渡します。 (もしくはlboundとuboundを渡す) サブルーチンでは渡されたサイズを元に処理します。
お礼
回答ありがとうございます。1次元配列はサイズを渡さなくてもできたと思いますが、高次になると渡す必要があるということですね。2,3次元配列も結局は1次元ですが、どのような折り畳みになっているか不明ですので。