我从文本 Numerical Recipes 中获取了以下函数ran0
。我编写了自己的计划random2
来致电ran0
。
为什么此代码会导致分段错误?谢谢你的时间。
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
答案 0 :(得分:5)
将常量6.0作为IDUM伪参数传递给函数。然后(尝试)使用诸如idum = ieor(...)等行修改此参数。您实际上是在尝试修改常量。
6.0的值已经修复了一段时间 - 足够长,以至于大多数程序员都希望在5.0到7.0之间找到它。请不要尝试改变它。
答案 1 :(得分:2)
扩展IanH的答案,如果你在更现代的Fortran中部分重写它:
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)