0
program bisect
real(8) ::  output
call bisection(3.d0,4.d0,2.d0,output)
print*, output
end program bisect

subroutine bisection(a,b,error,result)
real(8):: a,b,error,c,result
logical:: proceed
  proceed = .true.
  do while (proceed)
  if (sin(a)*sin(b).lt. 0.d0) then
     c=(a+b)/2
     if (sin(a)*sin(c).lt.0.d0) then
        b=c
     else
        a=c
     end if
  else  
     stop 'cannot be bisected'
  end if 

  if (abs(a-b).lt. error) then
     proceed = .false.
  end if
 end do
 result= a
end subroutine bisection

此处上传了相同代码的版本。

这是我能想到的最小例子。这会在使用 gfortran 以及在网站上运行可执行文件时产生分段错误。

4

1 回答 1

2

虚拟参数 a 和 b 与作为常量的实际参数相关联。常量是不可定义的——你的程序试图改变“3.0d0”或“4.0d0”的值。如果你的程序成功了,那么整个宇宙就会爆发混乱。

我强烈推荐:

  • 使用模块过程。这允许编译器检查实际参数是否与虚拟参数一致。
  • 在您的虚拟参数定义上使用 INTENT 规范。这允许编译器检查需要修改的东西是否是可修改的,以及不可修改的东西是否不是。

解决问题的方法是在主程序中使用适当的变量来保存初始值 3.0d0 和 4.0d0,并将这些可修改的变量传递给子程序。或者,您可以在子例程中创建虚拟参数的临时副本。在 F2003 中,VALUE 属性可用于自动执行此操作。

当我们这样做时 - 在所有范围内使用 IMPLICIT NONE。总是。

于 2013-02-11T19:51:58.997 回答