0

NumericalRecipesran0というテキストから次の関数を取得しました。を呼び出すために独自のプログラムを作成しました。 random2ran0

このコードがセグメンテーション違反を引き起こすのはなぜですか?御時間ありがとうございます。

FUNCTION ran0(idum)
  INTEGER idum,IA,IM,IQ,IR,MASK
  REAL ran0,AM
  PARAMETER (IA=16807,IM=2147483647,AM=1./IM,IQ=127773,IR=2836,MASK=123459876)
  INTEGER k
  idum=ieor(idum,MASK)
  k=idum/IQ
  idum=IA*(idum-k*IQ)-IR*k
  if (idum.lt.0) idum=idum+IM
  ran0=AM*idum
  idum=ieor(idum,MASK)
  return
END FUNCTION

PROGRAM random2
  IMPLICIT NONE
  REAL :: ran0
  PRINT *, ran0(6)
END PROGRAM
4

2 に答える 2

5

定数 6.0 を IDUM 仮引数として関数に渡します。次に、この引数を idum = ieor(...) などの行で変更 (しようと) します。事実上、定数を変更しようとしています。

6.0 という値は、しばらくの間固定されています。ほとんどのプログラマーは、5.0 から 7.0 の間のどこかにあると予想しています。変更しようとしないでください。

于 2013-03-05T22:33:39.773 に答える
2

これをより現代的な Fortran で部分的に書き直すと、IanH の回答が拡張されます。

module my_subs

contains

FUNCTION ran0(idum)
  INTEGER, intent(inout) :: idum
  INTEGER IA,IM,IQ,IR,MASK
  REAL ran0,AM
  PARAMETER (IA=16807,IM=2147483647,AM=1./IM,IQ=127773,IR=2836,MASK=123459876)
  INTEGER k
  idum=ieor(idum,MASK)
  k=idum/IQ
  idum=IA*(idum-k*IQ)-IR*k
  if (idum.lt.0) idum=idum+IM
  ran0=AM*idum
  idum=ieor(idum,MASK)
  return
END FUNCTION

end module my_subs

PROGRAM random2
  use my_subs
  IMPLICIT NONE
  !REAL :: ran0
  PRINT *, ran0(6)
END PROGRAM

属性を使用して引数を入力と出力の両方として識別しintent(inout)、サブルーチンをモジュールに配置し、そのモジュールを使用してコンパイラが引数の一貫性をチェックできるようにすると、コンパイラはこの問題を発見する可能性があります。たとえば、gfortran は次のように出力します。

PRINT *, ran0(6)
              1
Error: Non-variable expression in variable definition context (actual argument to INTENT = OUT/INOUT) at (1)
于 2013-03-06T00:13:59.760 に答える