我希望有人能够查看我的夏季项目代码,并让我知道我在哪里搞砸了。这是随机行走,但我做到了,这样当行走者超过6时,它又回到1,反之亦然。另外,当有多个步行者时,程序将确保只有两个最大步行者可以占用相同的“站点”。每当我尝试通过SilverFrost和Geany构建该程序时,它都会失败,而当我使用在线Fortran构建器并使其打印而不是将数据写入文本文件时,它将起作用。错误消息是
错误112,引用未定义的变量,数组元素或函数结果(/ UNDEF)主-在dddd.f95文件的第102行[+ 0c8d]
第102行是这样:
position(e,n)=position(e,n)+2
代码如下:
program FiniteRandomWalkWithSites
implicit none
integer :: position(4,1000),n,y,g,m,z,e ! The 2 used in the declaration can be changed in order to create n-number of walkers
real::x,onethird,twothird
real, dimension(1000)::random
onethird=1.00/3.00
twothird=2.00/3.00
do n=1,1000
position(1,n)=n
end do
do z=2,4 !Despite the fact that this do loop is redundant with just 1 "position column", the ending value ought to be modified to the same value as the one made on line 3
y=1
m=0
do n=1,1000
call random_number(x)
random(n)=x
if (x .le. onethird) then
m=y+1
if (m .gt. 6) then
m=1
y=m
position(z,n)=m
else if (m .lt. 1) then
m=6
y=m
position(z,n)=m
else
m=m
y=m
position(z,n)=m
end if
else if ((x .gt. onethird) .and. (x .le. twothird)) then
m=y-1
if (m .gt. 6) then
m=1
y=m
position(z,n)=m
else if (m .lt. 1) then
m=6
y=m
position(z,n)=m
else
m=m
y=m
position(z,n)=m
end if
else
m=y+0
if (m .gt. 6) then
m=1
y=m
position(z,n)=m
else if (m .lt. 1) then
m=6
y=m
position(z,n)=m
else
m=m
y=m
position(z,n)=m
end if
end if
end do
end do
jloop:do z=2,4
ploop:do n=1,1000
if ((position(z,n) .eq. position(z+1,n)) .and. (position(z,n) .eq. position(z+2,n))) then
call random_number(x)
if (z .eq. 2) then
if (x .le. onethird) then
e=z
else if ((x .gt. onethird) .and. (x .le. twothird)) then
e=z+1
else
e=z+2
end if
else if (z .eq. 3) then
if (x .le. onethird) then
e=z
else if ((x .gt. onethird) .and. (x .le. twothird)) then
e=z+1
else
e=z-1
end if
else if (z .eq. 4) then
if (x .le. onethird) then
e=z
else if ((x .gt. onethird) .and. (x .le. twothird)) then
e=z-1
else
e=z-2
end if
end if
end if
if (random(n) .le. onethird) then
if (x .lt. .50) then
position(e,n)=position(e,n)+1
if (position(e,n) .gt. 6) then
position(e,n)=1
end if
else if (x .gt. .50) then
position(e,n)=position(e,n)+2
if (position(e,n) .gt. 6) then
position(e,n)=1
end if
end if
else if ((random(n) .gt. onethird) .and. (random(n) .le. twothird)) then
if (x .lt. .50) then
position(e,n)=position(e,n)-1
if (position(e,n) .lt. 1) then
position(e,n)=6
end if
else if (x .gt. .50) then
position(e,n)=position(e,n)-2
if (position(e,n) .lt. 1) then
position(e,n)=6
end if
end if
else
if (x .lt. .50) then
position(e,n)=position(e,n)+1
if (position(e,n) .gt. 6) then
position(e,n)=1
end if
else if (x .gt. .50) then
position(e,n)=position(e,n)-1
if (position(e,n) .lt. 1) then
position(e,n)=6
end if
end if
end if
end do ploop
end do jloop
do g=1,1000
print*, position(1,g),position(2,g),position(3,g),position(4,g)!...position(a,g) [where a is rightmost column #]
end do
end program FiniteRandomWalkWithSites
答案 0 :(得分:0)
我不明白为什么该Fortran程序无法构建
我也不是。可能是因为它在很多方面都被破坏了。根据编译器和传递的特定编译选项,它可能或可能无法编译。在运行时也会可能或可能 崩溃。
错误112,引用未定义的变量,数组元素或函数结果(/ UNDEF)主-在dddd.f95文件的第102行[+ 0c8d]
我的编译器实际上已经编译,但是在运行时给出了更好的错误报告:
forrtl:严重(194):运行时检查失败。变量'FINITERANDOMWALKWITHSITES $ E'未在'。\ main.f90(102,17)'中使用
变量e
尚未定义就到达程序的这一点。这是什么意思? Fortran Standard调用“已定义” 具有有效值的数据对象。粗略地说,这意味着您在程序运行的任何先前时间都已为此变量分配了一个值。 “也许我在上一个if块中为它分配了一个值!” ,您可能会说。
if ((position(z,n) .eq. position(z+1,n)) .and. (position(z,n) .eq. position(z+2,n))) then
call random_number(x)
if (z .eq. 2) then
if (x .le. onethird) then
e=z
! (...)
end if
问题是:如果不满足if语句的条件(并且在很多迭代中不满足,取决于生成的随机数),则内部代码将不会执行。如果在第一次迭代中发生这种情况,则您尚未在任何时候通过if构造体,并且e
在到达指示的代码行时从未赋予它任何值。错误。
编译器不应在编译时检测到这种错误,这就是为什么它如此奇怪以至于您无法对其进行编译。也许您的编译器可以解析和扫描代码的所有条件分支,并寻找可能未定义的变量。老实说,我从未见过。
但这并不重要。此处重要的是,这是一个 severe 错误,并且您的程序可能会由于访问冲突而崩溃(或者,很不幸,不是),也就是说,当您尝试访问内存地址不是由程序管理的(或写为只读的),有时是由于数组越界问题引起的。
怎么会发生?好吧,默认情况下,Fortran不在运行时检查数组索引。您应该在代码时间这样做。如果e
是未定义的(并且您没有指定未定义变量的检查作为编译器选项),而您尝试使用它,则它的值可能包含一些已在其使用的内存地址上设置的垃圾值。这是潘多拉盒子,用于各种不可预测的行为。例如,如果e
的值为0,则position(e,n)=position(e,n)+2
会尝试查找数组的列0(可以是系统的任何其他内存地址)并尝试写入/读取它。如果不崩溃,则会产生错误的结果。
在您的else
构造中添加一个if
子句,该子句通常将值设置为e
。它将是什么值取决于您的程序逻辑-您将自己弄清楚。
if ((position(z,n) .eq. position(z+1,n)) .and. (position(z,n) .eq. position(z+2,n))) then
call random_number(x)
if (z .eq. 2) then
if (x .le. onethird) then
e=z
! (...)
else
e = some value that makes sense for your program
end if
呃...不。您应该真正查看所有程序逻辑和结构,然后进行调试。有很多细节要解决。例如,当数组的形状为position(z+1,n)
时,您将在position(z+2,n)
的循环中执行z=2,4
和(4,np)
。 z=3
或z=4
会发生什么?您可能应该在call random_number(x)
之前初始化随机种子。另外,您可以通过不对数组维数或其他参数进行硬编码来查看诸如使算法更抽象等内容。
我强烈建议您在开发代码时打开所有用于检查和警告的编译选项,特别是检查未定义的变量和边界检查。