1

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

 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。

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

4

2 回答 2

3

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

将所有子例程和函数放在模块use中,这将确保您正确调用它们,或者至少不是完全错误。这是 Fortran 90 及更高版本的发展方向。只有当你真的需要时才避免它。

return 语句是多余的,子程序无论如何都返回 et end,它还应该做什么呢?

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

于 2012-11-05T17:19:42.513 回答
1

我同意 Vladimer F 的观点。隐式输入是有害的。还有使用模块 为什么使用 FORTRAN 77 改进版本的 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
于 2012-11-05T17:33:53.100 回答