Fortran:在函数中调用子例程

时间:2012-11-05 17:02:13

标签: segmentation-fault fortran gfortran fortran77

我正在构建一个程序,它必须在函数子程序中调用子程序,并且能够在主程序中调用相同的子程序。

 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的末尾使用include语句。

我在这个网站上搜索了类似的问题,只能找到关于fortran 90的帮助。我正在使用gcc 4.6.1中的gfortran。

编辑:我解决了这个问题。我试图在函数中调用的子例程同时具有数字和字符输出。我忽略了字符输出,没有字符定义变量来处理字符输出。一旦我在函数中定义了一个字符变量,一切都运行正常。感谢大家的耐心和帮助。

2 个答案:

答案 0 :(得分:3)

如果您真的不必使用FORTRAN 77,请不要使用它。即使在Fortran 77中忘记IMPLICIT!几乎所有FORTRAN 77编译器中都存在IMPLICIT NONE作为扩展。在过去25或30年的所有合理的代码中几乎是必要的。这是60年代,也许是早期70年代缩短代码的方式。

将所有子程序和函数放在模块和use中,这将确保您正确地调用它们,或者至少不是完全错误的。这是Fortran 90及以后的方式。只有当你真的需要时才能避免它。

返回语句是多余的,无论如何,子程序返回到结尾,还应该做什么呢?

最后,我在编译代码时没有发现任何错误或编译器警告。我甚至使用过valgrind。我还在Linux上使用了gfortran-4.5.4和gfortran-4.6.3以及Solaris Studio。

答案 1 :(得分:1)

我同意Vladimer F.隐式打字是有害的。还使用模块为什么在Fortran的改进版本可用多年后使用FORTRAN 77?我尝试的时候你的程序工作了。这是对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
相关问题