我正在构建一个程序,必须在功能子程序中调用子例程,并能够在主程序中调用同一子例程。
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中制作模块。子例程必须能够在功能和主程序中访问。我当前的程序结构具有功能,子例程分为两个单独的.f文件,并且在MAIN末尾使用了语句。
我搜索了该网站的类似问题,只能在Fortran 90上找到帮助。我正在使用GCC 4.6.1的GFORTRAN。
。编辑:我解决了问题。我试图打电话给该函数的子例程具有数值和字符输出。我忽略了字符输出,并且没有字符定义的变量来处理角色输出。一旦我在功能中定义了一个字符变量,一切正常。谢谢大家的耐心和帮助。
如果您真的不必使用Fortran 77,请不要使用它。即使在Fortran 77中,也忘了IMPLICIT
!IMPLICIT NONE
几乎所有Fortran 77编译器都存在作为扩展程序。在过去的25或30年中,所有理智代码几乎都是必要的。这是60年代,也许是70年代初期缩短代码的方式。
将所有子例程和功能都放在模块中,并将其放置在use
中,这将确保您正确调用它们,或者至少不是完全错误的。这是90岁的Fortran及以后的路。仅在您真正必须的时候避免它。
返回语句是多余的,子例程返回et e the End the End,它还应该做什么?
最后,我在编译代码时没有发现任何错误或编译器警告。我什至使用了valgrind
。我还使用了Gfortran-4.5.4和Gfortran-4.6.3,以及Linux上的Solaris Studio。
我同意vladimer F.隐式打字是有害的。同样,使用模块,为什么在改进的Fortran版本中使用了这么多年?当我尝试时,您的程序有效。这是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