• 締切済み

隔絶されているサブルーチン間の通信の方法

以下のようなFortranのサブルーチンとモジュールがあります。これを見ると、サブルーチンA,Bはモジュールa,bが別なのでデータ的に隔絶されていることになります。もし、このような場合、サブルーチンA,Bの間で何らかの変数を共有するようなことをしたい場合、どのような方法があるでしょうか。サブルーチンの引数を使うのは混乱の原因になりそうなので、できればmoduleの方で処理できないかと思うのですが。 混乱しそうなところなので、やり方をいろいろ比較して見てみたいと思います。Cではグローバル変数のように全体で共有する変数を用意するのかなと思いますが。 module a end module module b end module subroutine A use a end subroutin B use b end Fortranについてはここでは特設会議室はありませんが、どこかいいところがあるでしょうか。Cの専門家はいろんなことに通じていると思うのでここにお尋ねしました。よろしくお願いします。

みんなの回答

noname#245936
noname#245936
回答No.2

んー。 であれば、マルチスレッドのプログラムを書くとか、実行ファイルを別にして、媒介にデータベースサーバ使うぐらいですかね。 マルチスレッドはよくある話で、例えばファイルをダウンロードするときに画面で進捗バーを表示しますが、あればファイルのダウンロードと進捗のバーは並列で処理しています。 片方が終わるまで待つと画面が固まっちゃいますので。 ただ、数値シミュレーションであればAプログラムとBプログラムがあって、Aプログラムが自分の実績を書いた後で、BプログラムがAプログラムの結果を見て動けばいいと思いますのでデータベースさえあればいいように思います。

noname#245936
noname#245936
回答No.1

FORTRAN 言語はわかりませんが、C言語など他の言語では、全体的にグローバル変数はより少ないに越したことがなく、変数のスコープはより狭い方がいいことだとされています。 グローバル変数よりモジュール変数、モジュール変数よりローカル変数がいいです。 理由は、大きいプログラムを書く時に、変数のスコープが広いとどこからでも変数中身がさわれてしまい、バグ箇所のトレースが非常に難しくなる点。 また、複数人で同時並行開発する際に、変数のスコープが広いものばかりだと分業化しづらく、互いに変数を潰し合うから。 さらに、各モジュールが簡潔にまとまって独立性が高いと、他のプログラムにそのまま流用しやすくなり、開発期間と費用が落とせるためです。 それの最たるものかフレームワークやライブラリなどですね。 命令を書くだけで、中の詳細処理が分からなくても処理ができるのが理想です。 試しに10,000行超えるようなプログラム書くと分かります。自分で書いたプログラムが、スコープが広い変数が多いと、途端に訳がわからなくなります。 こういうのをオブジェクト指向とか、パッケージングとか、ボクシングど言ったかと思います。

skmsk1941093
質問者

お礼

回答ありがとうございます。今回のものは2つの通信がないとやる意味がないものになっています。物理数値シミュレーションのようなもので、例えば海と空を別々に計算するけど、両方が接している海面では相互作用してしまうということになります。ここで情報共有が必要というわけです。 まさかの方法は外部ファイルに書き出して読み込むということです。データの共有が計算の律速となる部分(ホットスポット)ではないと判断してそうする可能性がなくはありませんが。やはり通信してほしいと思うのですが。オブジェクト指向のようなことになると自信がなくて足元が揺らぐ思いです。

関連するQ&A

  • モジュールとなったライブラリ集の利用法

    以下、長文ですみません。 サブルーチンとか関数に関するプログラム集というものがあり、自分でメインを適当に作ってそれらを呼び出して使うというライブラリ集のようなものがあります。昔からあるもので各言語に応じた本なども多数出版されています。 Fortranなのですが、F77の頃は以下のパターンが1つのファイルで延々と1万行ぐらい続くものです。ファイル名:A.f ---------------- 以下の形式のサブルーチン群の羅列 subroutine abc() いろいろ return end ---------------- このようなものは、例えば、 gfortran -c A.f としてリンクなしでコンパイルし、オブジェクトA.oが出力され、 メインプログラム(B.f)から呼び出す場合、 gfortran B.f -o A.o とすると、実行形式が出力されます(ここまで前置きが長くてすみません)。 さて、Fortran95だと状況が一変します。 A.f95だと以下のように変更されています(A.fの後継としてのA.f95)。 ------------- module A interface.... public... private... そしてサブルーチン群 subroutine abc() いろいろ return end subroutine abc end module A ------------ これを gfortran -c A.f95 とリンクなしでコンパイルすると、A.mod, A.oという2つのファイルが出力されます。 その後、メイン(B.f95)の作成ですが、モジュールA.modを読み込むため、 USE A を先頭にし,中身をF95のフォーマットにしています。その後、 gfortran B.f95 -o A.o あるいは gfortran B.f95 とするのですが、B.f95からcallしているA.f95の中のサブルーチンが発見できないというエラーになります。これら(A.f95, B.f95, A.o, A.mod)はすべて同一フォルダ内部のファイルです。 ここで万事休すなのですが、何かFortran95の処理で間違っているところがあるでしょうか。私がFortran95の処方を間違っているからではないかと思いますが、対処方法についてもしご存じでしたら、よろしくお願いします。 ※カテゴリ違いかもですが、ここしか聞く当てがないと思っています。

  • サブルーチンに引数を2つ以上渡したい

    Access2002、vba上で サブルーチンに引数を2つ指定したいのですが、 なぜか「コンパイルエラー 修正候補=」 と出てしまいます。 引数を1つにするとうまく動作します。 どなたかお分かりの方いらっしゃいましたら教えて ください。 宜しくお願いします。 サンプルコード: -------------------------------- the_subroutine(a, b) ' ※ここでコンパイルエラー Sub the_subroutine(c As String, d As Object) End Sub -------------------------------

  • リファレンスをサブルーチンの戻り値にしてもOKですか?

    ■ サブルーチン内部で処理した結果を格納した、配列、ハッシュ、スカラーなどのデータを戻り値として利用する必要があります。その場合、どうするのが標準的なやり方でしょうか? ■ return (配列へのリファレンス, ハッシュへのリファレンス, スカラー); などとやってしまっても問題はないでしょうか? ■ 下のプログラムを試したところ、予想に反しちゃんと 「31415」と表示されました。 #!/usr/bin/perl -w sub subroutine{ my @a = (3, 1, 4, 1, 5); return \@a; } my $b = subroutine{}; print @$b; ■ サブルーチン内部で使用した変数へのリファレンスをサブルーチン 外で使っていいのだろうか? サブルーチンの処理が終了した時点でサブルーチン内部で使用した 変数はメモリーから消去されるのかと思ったものですから。

    • ベストアンサー
    • Perl
  • フォートランの動作に関する質問

    以下のような短いフォートランプログラムがあります。OS:Windows10 module com integer,parameter ::nd=10 end module program main use com print *, nd call sub stop end subroutine sub use com print *, nd return end 内容はモジュールで宣言したパラメータを確認してみるということです。 このプログラムがgfortranで動作せず、intel fortranでは全く問題ありません。 gfortranの結果は以下のようです。 f951.exe: Fatal Error: Reading module 'com' at line 1 column 1: Unexpected EOF GNU Fortran (Rev1, Built by MSYS2 project) 9.3.0 Copyright (C) 2019 Free Software Foundation, Inc. gfortranのこのバージョンに何か問題があるのでしょうか。前からすこしおかしいことには気づいていたのですが。私のコードに問題があるでしょうか。 ※Cが一番近いと思いましてこちらに上げました。

  • 配列Xの最大値、最小値を求めるサブルーチンmaxminの作り方

    配列Xに入っているデータの最大値、最小値を求めるサブルーチンmaxminの作り方を教えてください。(n:データ数) subroutine maxof(x,n,xmax,xmin) implicit real*8(a-h,o-z) real*8 C 最大値は変数xmaxに、最小値は変数xminに代入する  !!この部分が分かりません!! return end 教えてください。 よろしくお願いします。

  • フォートランのサブルーチンの内部変数

    すみません。科学技術系の人間でして、フォートランが現役なのです。 あるプログラムのことですが、サブルーチンの内部の変数についてサブルーチンを呼び出すごとに加算していくようなことを行っています。 do i=1,100 call abc(i)   ← サブルーチンabcを100回呼び出す enddo end subroutine abc(i) n=n+1        ←呼び出されるたびに和をとる。 write(*,*) n return end このようなシンプルなプログラムは問題ないのですが、少し複雑になるとどういうわけか、呼び出される度にnが初期化され、writeさせた結果常に1が表示されるという現象に会いました。 昔のコンパックフォートラン(MS-Fortran, DEC Fortranを継承)と、最近のIntel Fortran(最新版)で動作が異なります。前者では和を取ってくれますが、後者では初期化されて常に1が出力されます。(上記のプログラムは問題なしです。もう少し長いプログラムでの問題です。) 言語仕様の問題(すなわちフォートランのバージョン)なのか、コンパイラ仕様の問題なのか、C言語のように宣言の仕方で変ったりするようになったというようなことはないでしょうか。 以下に示すように和をとる変数をメインプログラム側に一旦見えるようにすると、インテル版でも思ったとおりの動作をします。 call abc(i,n) suboroutine abc(i,n) としてnをメイン側に露出する。 よろしくお願いします。

  • Fortranのサブルーチン引数について

    他人が作ったFortran(恐らくFortran77)のプログラムで計算をしようとしています。 コンパイルはできるのですが,実行するとエラーが出てしまい困っています。 エラーメッセージは 「forrtl:severe(157):Program Exception - access violation」 となっていて,実行時エラー番号で調べると 「プログラムが適切な参照権を持っていない仮想アドレスに書き込み,または読み取り を行おうとした」と出ていました。 Fortran初心者の自分にはイマイチ意味が判らないのですが,エラーが出た後に サブルーチンのある決まった場所に黄色い矢印が示されます。 そこで今,その部分のサブルーチンを確認しているところです。 前置きが長くなってしまいましたが サブルーチンの中を確認している途中で疑問に思った所が一つあります。 問題のサブルーチンは --------------------------------------- call dbesl(EN,0,BX0,BY0,BI0,BK0)     subroutine dbesl(X,NOR,BX,BY,BI,BK) FN = NOR  ・  ・  ・ 11 NOR = FN               <---この行に黄色い矢印が出る return end --------------------------------------- となっているのですが,サブルーチンを呼び出すcall文の所で 2つ目の引数が『0』となっているのは正しい使い方なのでしょうか? どうもサブルーチン内の計算をしてメインプログラムに引数を返す所が おかしいような気がしています。 因みにメインプログラムに戻る際の"FN"の値は『0』となっていました。 コンパイラはCompaq Visual Fortranを使用しています。 足りない情報は出来るだけ追記していきますので,ご教示宜しくお願いします。

  • Perlです。サブルーチンについて

    以下の文はあっていますでしょうか。 # サブルーチンを呼び出して引数は 3 とする。 # そして返ってきた戻り値を変数$aに代入せよ。 $a=&a(3); # サブルーチン名aせよ。 sub a{ # $_[0]が引数 3 となりプラス1して変数$bに代入せよ。 $b=$_[0]+1; # 変数$bの内容を戻り値として返せ。 return $b; } # 変数$aの内容を表示せよ。 print "$a";

    • ベストアンサー
    • Perl
  • fortran 配列宣言のオーバーフロー

    fortranの配列宣言について質問です。 下記の様に配列の変数をサブルーチンの内外で宣言することで違いが出てきました。 こういうものなのでしょうか。失礼します。 parameter(ine=4999) c call test1(ine) !error call test2() !OK stop end subroutine test1(ine) dimension ary1(ine,50) return end subroutine test2() parameter(ine=4999) dimension ary1(ine,50) return end

  • サブルーチンについて

    下記のようなソースコードを書いたところエラーが出てしまいました。 $sum = $sample2($a); の箇所でエラーが起こっているようなのですが、解決の仕方が分かりません。 &sample1(5,'&sample2'); sub sample1 { ($a,$sample2) = @_; $sum = $sample2($a); print $sum; } sub sample2 { ($a) = @_; $b = 10; $sum = $a + $b; return $sum; } このように、サブルーチンの中に更にサブルーチンを書いて、なおかつそのサブルーチン名を一旦変数に格納して使用する場合はどのようにプログラムを書けば良いのでしょうか?? ""で囲ったりといろいろとしてもダメでした。 もちろん、$sum = $sample2($a); ではなく $sum = sample2($a); のように書けば良いとは思うのですが、一度サブルーチン名を変数に入れてから使用する場合はどのようにすれば良いのでしょうか?? ご回答の程よろしくお願い致します。

    • ベストアンサー
    • CGI

専門家に質問してみよう