すみません。科学技術系の人間でして、フォートランが現役なのです。
あるプログラムのことですが、サブルーチンの内部の変数についてサブルーチンを呼び出すごとに加算していくようなことを行っています。
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をメイン側に露出する。
よろしくお願いします。
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
元々のFORTRANの仕様で、サブルーチン内の変数は保証されなくてもかまいません。
これは、FORTRANの最初の仕様が決められた当時のコンピュータではメモリ容量が少なかったため、サブルーチンは呼び出される度にディスクからメモリにロードされていたため、変更された内容を保存する事ができなかったためです。これは、サブルーチンの変数をスタックに置かないGCOSのFORTRANなどでも同様です。確実に値を保持したいなら、以下のいずれかの方法を使ってください。
・Nを引数に含める
・Nを名前無し共通領域(ブランクコモン)に置く
・Nを名前付き共通領域(レーベルドコモン)に置く
・SAVE文を使う
No.2
- 回答日時:
初期化されていない、また保存もされていない変数は、
コンパイラが変われば扱いは変わりますし、コンパイル
オプションが変わっただけでも値が変わる性質のものです。
変数の扱い方に誤りがあると言わざるを得ません。
一般的に、サブルーチンが自分を呼び出した回数を計算する
こと自体、機能的強度の落ちる性質を持つように思われます。
複数の場所から呼び出すので仕方がない場合でも、なにか工
夫をしたいところです。
今回のケースに限って言えば、nの計算をする必要はなく、
目的の値はiにあります。
No.1
- 回答日時:
局所変数は,実行時にスタックに積まれるのが普通ですから,変数の値は保持されなくても文句は言えません。
サブルーチン内で値を保持したい変数にSAVE属性を付けてあげましょう。コンパイラのオプションで全ての変数をstaticにしてもよいですね。Intelコンパイラの場合は-saveか/Qsaveです。
昔の普通のコンパイラはsave属性がついているのがデフォルトでしたが,今は違います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) FORTRAN77の配列(除算) 2 2023/02/01 14:34
- Ruby VBA 2 2023/01/14 14:14
- C言語・C++・C# C言語 3 2022/10/04 15:07
- その他(自然科学) 科学技術計算の仕事について 2 2023/02/04 18:09
- Visual Basic(VBA) ファイル全てを .xlsm に変更したところ、プログラムが途中で落ちてしまっています 17 2022/12/07 12:03
- 数学 …こりゃ酷すぎる。回答者諸君、しっかりしなさい。初等的な問題にはまず初等的な解法を示すべきと心得よ。 7 2022/04/11 22:00
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- C言語・C++・C# 至急お願いします。C言語で.imgのファイルを読み込んで1バイトづつ出力するプログラムを作りたいので 3 2023/01/16 22:49
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# c言語 コマンドライン引数 4 2023/02/09 18:47
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
例外処理のフローチャートの記...
-
COBOLで、Shellを起動するには?
-
Excel VBAで、ユーザーフォー...
-
VBAで2重のDoLoop関数から抜け...
-
オフコン(富士通Kシリーズ)...
-
perlの構文でカンマの意味が分...
-
サブルーチンを認識しません。
-
VisualBasicで外サブってできる...
-
Perlのサブルーチンの引数引継ぎ?
-
ExcelVBA AddinでOnAction
-
VBAでoutlook365が起動しません。
-
VBAで別モジュールへの変数の受...
-
VBSがコンパイルエラーになりま...
-
Excel VBAでリンク切れをチェッ...
-
laravel 本番環境でメールが送...
-
モジュールとは何ですか
-
Excel VBAで、ユーザーフォーム...
-
'Range'メソッドは失敗しました
-
モジュールの最大数はいくつな...
-
VBでグローバル変数を宣言するには
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
例外処理のフローチャートの記...
-
Excel VBAで、ユーザーフォー...
-
モジュールとサブルーチン
-
perlの構文でカンマの意味が分...
-
COBOLで、Shellを起動するには?
-
ACCESSのVBAでPrivate Sub ~en...
-
GOSUB命令とは
-
サブルーチンを認識しません。
-
エクセルVBAでサブルーチン...
-
ExcelVBA AddinでOnAction
-
Excel VBAから利用できるフリー...
-
初歩的な質問なのですが、サブ...
-
VBAのサブルーチンとプロシージ...
-
VBAで2重のDoLoop関数から抜け...
-
Attempt to free unreferenced ...
-
オフコン(富士通Kシリーズ)...
-
初心者です。Perlではどんな時...
-
”:”がいっぱいの文について。
-
サブルーチンやif分以外での中括弧
-
fortran95実行エラー
おすすめ情報