• ベストアンサー

サブルーチンについての質問デス

サブルーチンについての質問です。 サブルーチンの中で設定した変数が、そのサブルーチンを呼び出す度に初期化されてしまいます。 (例えば初めてサブルーチンを呼び出し、そのサブルーチンを抜ける時にはx=10と記憶されているのに、また次にそのサブルーチンが呼び出される時には、x=0となっている。) これをx=10のまま記憶させておき、引き続きサブルーチンの中でこの値を使う事は不可能なのでしょうか? 乱文で申し訳ありませんが、よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • singlecat
  • ベストアンサー率33% (139/418)
回答No.4

基本的な事を言うと、PUBLICやSTATICを使うのは、極力避けるべきです。 例えばPUBLICの場合は、プロジェクト全体で使えるので、どこでその変数の値を操作されているのかが解りにくくなります。 上位の変数を引数として参照渡しにするなどで対応されてはどうですか?

fbwpt031
質問者

お礼

簡潔で非常に分かり易い答えをありがとうございます。 変数レベルを変えるよりは、引数として参照渡しをした方が複雑にならずに済みそうですね。 ありがとうございました。

その他の回答 (3)

  • AKARI0418
  • ベストアンサー率67% (112/166)
回答No.3

Staticと用途は異なりますが、Public宣言(プロジェクトレベル)やPrivate宣言(モジュールレベル)にすることで保持することもできます。 Public宣言であれば宣言したプロジェクトが動作中であれば変数の初期化が行われません。 Private宣言であれば宣言したモジュール内であれば、変数を使いまわすことができます。 VB.NETであれば、アプリケーションの設定を追加しプロパティを作成して使うことで、プログラムを終了しても保持することができます。 VB6.0以前のバージョンであればiniファイルを作成し、API関数GetPrivateProfileString関数を使用しiniファイルの情報を使用するというのが一般的ではないでしょうか。プログラムの設定値をテキストファイルの変更だけで行えるので、なかなか便利だと思います。

fbwpt031
質問者

お礼

詳しい説明ありがとうございました。 この様な解決法もあるとは…奥が深いです。。 とても参考になりました。

  • ya-cha
  • ベストアンサー率38% (27/70)
回答No.2

一番簡単なのは、記憶させておきたい変数の宣言をstaticにしておく事です。 staticを付加することで、処理中ずっと値を保持します。 僕も今月勉強を始めたばかりです。頑張りましょう!

fbwpt031
質問者

お礼

回答ありがとうございます。 僕もついこの間から独学で勉強を始めており、色々と苦しんでいます。 心強いお言葉ありがとうございました。 ぜひ共に頑張りましょう!

  • FEX2053
  • ベストアンサー率37% (7987/21355)
回答No.1

変数の寿命をちゃんと考慮してますか? http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard8.htm クラスレベルの宣言にするとか、Staticで宣言するとか、方法はいくつか あります。

fbwpt031
質問者

お礼

分かり易いサイトの紹介、どうもありがとうございます。 変数のレベルを変えたり、引数として引っ張ってきたりなど色々と方法はあるのですね。 非常に参考になりました。ありがとうございます。

関連するQ&A

  • サブルーチンについて

    サブルーチンについての質問です。 サブルーチンの中で設定した変数が、そのサブルーチンを呼び出す度に初期化されてしまいます。 (例えば初めてサブルーチンを呼び出し、そのサブルーチンを抜ける時にはx=10と記憶されているのに、また次にそのサブルーチンが呼び出される時には、x=0となっている。) これをx=10のまま記憶させておき、引き続きサブルーチンの中でこの値を使う事は不可能なのでしょうか? 乱文で申し訳ありませんが、よろしくお願いいたします。

  • サブルーチンについて

    下記のようなソースコードを書いたところエラーが出てしまいました。 $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
  • 希望のサブルーチンを読み出すプログラムを教えてください。

     まずお断りをしておきます。  初心者なので、変な表現をしていたら申し訳ありません。  お聞きしたいのは、「複数のサブルーチンを用意しておいて、ある変数の値に対応して希望のサブルーチンが呼び出せるようにするにはどうすればよいか?」と言う事です。  プログラムはできるだけ簡単にしたいです。  無茶な書き方だと思いますが、イメージとしては以下の通りです。 (コマンドもめちゃくちゃだと思います・・・。すみません。) ******************************** MAIN------------ FOR A=0 TO 10 GOSUB A NEXT SUB------------- 0: PRINT A RETURN 1: PRINT A RETURN  ・  ・  ・ 10: PRINT A RETURN ********************************  御回答、よろしくお願いします。

  • 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を使用しています。 足りない情報は出来るだけ追記していきますので,ご教示宜しくお願いします。

  • サブルーチンの@_とreturn

    勉強を始めて数日、サブルーチンが理解できずこまっています。長くてすみませんが、どなたか以下の解説をお願いします。 1 : $aa = "hello"; 2 : $kekka_sub_1 = $sub_1($aa); 3 : $kekka_sub_2 = $sub_2($aa); 4 : 5 : print "sub_1の結果: $kekka_sub_1"; 6 : print "sub_2の結果: $kekka_sub_2"; 7 : 8 : sub sub_1{ 9 : ($aa) = @_; 10: $aa = "Hanako!".$aa; 11: return $aa; 12: } 13: 14: sub sub_2{ 15: ($aa) = @_; 16: $aa = "Taro!".$aa; 17: return $aa; 18: } まず、line9と15の@_というのが一体何なのかわかりません。 @といえば配列全体を示すものと覚えているのですが、これがどこから来たのか・・・・。 次にreturnですが、これは実際には「line1の$aaへ戻れ」という意味なのかそれとも別の意味なのか・・・・・。 私の持っている本だと@_は、サブルーチンの引数が設定されている変数です。とあるのですが、実際何をしているところなのかが理解できません。 勉強を始めたばかりなので、わかりやす~い解説を頂けたらうれしいです。よろしくお願いします。

    • ベストアンサー
    • CGI
  • シーケンサのサブルーチンについて

    シーケンサのサブルーチンについて 三菱FXシリーズで勉強中です。 命令解説書によると、サブルーチンや割込みルーチン内でONさせたデバイスは、ルーチンを終了した後も保持されている。なお、リセット命令を実行するとリセット状態も保持される。従って、これらのデバイスは、ルーチン終了後メインプログラムの中でリセットするか、ルーチン内にリセット命令やOFF実行のためのシーケンスをプログラムしなさい。となっています。 このこと自体が相当に違和感があって、即座に納得しずらい内容ですが、それでもPLCとはこういうものかと無理やり納得しようとしています。 それでもどうにも納得できないのが、「OFF実行のためのシーケンスをプログラムしなさい」と言って、M8001にリセット命令(B命令の部分)を入れた点です。 もし、B命令が無ければX001の4~7パルスの間C0はゼロのままだそうです。 そもそもセット/リセット命令はそれを実行した時点で値を設定すれば終わりで、効果が持続する概念が理解できません。更にもっと不思議なのが、B命令です。M8001は常時OFFですから、Bのリセット命令は実行されないが、これが存在することによってリセット効果が継続するのを終わらせる意味があるという。これが全く納得できません。私の常識外の概念です。 PLCにはロード、アンド、アウトなどと機械語らしいニーモニックコードがありますが、機械語としてCPUが実行する言語ではなくて、インタープリターが理解するデータだろうと想像しています。 各デバイスは現在値と次の時間に持つ値の二つの入れ物を持って、それを順次歩進していると解釈すると、リセット状態が継続するなどの概念は入る余地も無いのです。 このあたりのことについて、私の非常識な頭を、仕組みから説き起こして納得させていただけるととてもありがたいのですが。 よろしくお願いします。

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

    すみません。科学技術系の人間でして、フォートランが現役なのです。 あるプログラムのことですが、サブルーチンの内部の変数についてサブルーチンを呼び出すごとに加算していくようなことを行っています。 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をメイン側に露出する。 よろしくお願いします。

  • 確率関数

    離散型の確率変数Xが、次のような確率関数を持つものとする。 P(x)=1/2(1-|x|/2) x=-1,0,1 YをXと同一の確率分布を持ち、かつXと独立の確率変数とする。この時、E(5X+3Y-2)とV(X-Y)WO 求めよ。という問題があるのですが、私の考える限り、Yの確率変数を自分で勝手に設定しない限り、解くのは不可能のように思います。そうすると自分で勝手に設定した値が残ってしまうように思います。実際はどうやって解けばいいのでしょうか。

  • 配列 x に入っているデータの最大値、最小値を求めるサブルーチンとそのヒストグラムの作り方

    配列 x に入っているデータの最大値、最小値を求めるサブルーチン maxmin(x,n,xmax,xmin) を作り方を教えてください。 n はデータ数。 最大値、最小値はそれぞれ xmin, xmax に代入する。 次に、そのサブルーチンを用い、x に入っているデータのヒストグラムを作成するプログラムを作り方も教えてください。 (途中までしか分かりません) implicit real*8(a-h,o-z) real*8 x(10000) integer count(100) ndiv = 40 分割数は 40 にする n = 10000 データ数は 10000 dummy = rand(13) 乱数の初期化 do 10 i=1, n sum = 0.0d0 do 20 j=1,5 sum = sum + rand(0) 5個の乱数の和 20 continue x(i) = sum 10 continue call maxmin(x,n,xmax,xmin) 最大・最小値を求める dx = (xmax - xmin)/ndiv 分割幅 !!count をゼロで初期化する do ループを追加!!(よく分かりません) !!ヒストグラムを作成する do ループを追加!!(よく分かりません) do 100 k=1, ndiv write(6,*) xmin+(k-0.5d0)*dx, count(k) データの中心値と個数を出力 100 continue stop end subroutine maxmin(x,n,xmax,xmin) implicit real*8(a-h,o-z) real*8 x(*) !!この部分を作成してサブルーチンの完成のさせ方が分かりません!! return end ところどころが分かりません。 とても困っていますし、急いでいます。 だれか教えてください。 よろしくお願いします。

  • シンプレックス法の質問です。

    シンプレックス法でfはx1,x2,x3,x4の関数であり、それを最小化したいとします。その途中で式を正準系に直し、fの変数の中で負で最も係数の大きいものを次の基底変数に選びます。では次の「非基底変数」にはどういうものをを選べばいいのでしょう?

専門家に質問してみよう