1

関数サブプログラムでサブルーチンを呼び出す必要があり、メイン プログラムで同じサブルーチンを呼び出すことができるプログラムを作成しています。

 program main
 implicit double precision (a-h,o-z)
 parameter (ncmax=20)
 dimension z(ncmax)

 xI=1.0
 xII=2.0
 z(1)=1.0

 outI = fncn (xI,xII,z,ncmax)

 call Sub (xI,xII,xIII,z)
 outII = 2.0*xIII

 end program


 function fncn (xI,xII,z,ncmax)
 implicit double precision (a-h,o-z)
 dimension z(ncmax)

 Call Sub (xI,xII,xIII,z)
 fncn = xIII

 return
 end function


 subroutine Sub (xI,xII,xIII,z)
 parameter (ncmax=20)
 implicit double precision (a-h,o-z)
 dimension z(ncmax) 

 xIII = xI + xII + z(1)

 return 
 end subroutine

これはすべて固定形式の Fortran 77 ('.f' 拡張子) です。表示されるエラーは、セグメンテーション違反です。このサイトの他の投稿のいくつかが示唆するように、モジュールを作成することになっていますか? 私はまだ初心者で、77 でモジュールを作成する方法がわかりません。サブルーチンは、関数とメイン プログラムでアクセスできる必要があります。私の現在のプログラム構造では、関数とサブルーチンが 2 つの別個の .f ファイルに分割されており、main の最後で include ステートメントが使用されています。

このサイトで同様の問題を検索しましたが、fortran 90 に関するヘルプしか見つかりませんでした。gcc 4.6.1 から gfortran を使用しています。

編集:問題を解決しました。関数で呼び出そうとしたサブルーチンには、数値と文字の両方の出力がありました。文字出力を見落としており、文字出力を処理するための文字定義変数がありませんでした。関数内で文字変数を定義すると、すべて正常に機能しました。皆様のご理解とご協力に感謝いたします。

4

2 に答える 2

3

FORTRAN 77 を本当に使用する必要がない場合は、使用しないでください。IMPLICITFortran 77 のことさえ忘れてください! IMPLICIT NONEほとんどすべての FORTRAN 77 コンパイラに拡張機能として存在します。過去25年または30年間、すべての正常なコードでほとんど必要です。コードを短縮するのは 60 年代、おそらく 70 年代初頭の方法でした。

すべてのサブルーチンと関数をモジュールに配置するとuse、それらが正しく呼び出されるか、少なくとも完全に間違っていないことが保証されます。これは Fortran 90 以降の方法です。本当に必要なときだけ避けてください。

return ステートメントは冗長です。サブルーチンはいずれにせよ終了します。他に何をすべきでしょうか?

最後に、コードをコンパイルするときにエラーやコンパイラの警告はまだ見つかりませんでした。私も使用しvalgrindました。また、gfortran-4.5.4 と gfortran-4.6.3、および Linux 上の Solaris Studio も使用しました。

于 2012-11-05T17:19:42.513 に答える
1

Vladimer F に同意します。暗黙の型付けは有害です。また、モジュールを使用して Fortran の改良版が長年にわたって利用可能であるのに、なぜ FORTRAN 77 を使用するのでしょうか? 私が試したところ、あなたのプログラムは機能しました。以下は、Fortran 90 への簡単で最小限の翻訳です。

module my_subs

implicit none

contains

function fncn (xI,xII,z,ncmax)
integer :: ncmax
double precision :: z(ncmax)
double precision :: xI, xII, xIII
double precision :: fncn

Call Sub (xI,xII,xIII,z,ncmax)
fncn = xIII

return
end function


subroutine Sub (xI,xII,xIII,z,ncmax)
integer :: ncmax
double precision :: z(ncmax)
double precision :: xI, xII, xIII

xIII = xI + xII + z(1)

return
end subroutine

end module my_subs


program main
use my_subs
implicit none
integer, parameter :: ncmax=20
double precision :: z(ncmax)
double precision :: xI, xII, xIII, outI, outII

xI=1.0
xII=2.0
z(1)=1.0

outI = fncn (xI,xII,z,ncmax)

call Sub (xI,xII,xIII,z,ncmax)
outII = 2.0*xIII

write (*, *) outII

end program
于 2012-11-05T17:33:53.100 に答える