对于您所面临的问题,现代 Fortran 有一个常见的模式(部分函数应用)。与其他语言不同,Fortran 没有函数闭包,因此为函数创建词法作用域有点“复杂”并且有点有限。
您确实应该考虑重新访问 @VladmirF 在评论中共享的所有链接,其中大多数直接适用于您的案例。我会给你一个解决方案的例子。
这是不使用包装类型的解决方案。我将使用 Fortran 2008 标准中包含的一项功能:将内部过程作为参数传递。它与最新的 gfortran、Intel 等兼容。
如果您无法访问具有此功能的编译器或者您更喜欢具有派生类型的解决方案,您可以参考this answer.
module without_custom_type
use, intrinsic :: iso_fortran_env, only: r8 => real64
use :: solver
contains
subroutine solve_quad(a, b, c, x0, x, iters, debug)
integer, intent(in) :: a, b, c
real(r8), intent(in) :: x0
real(r8), intent(out) :: x
integer, intent(out) :: iters
logical, intent(in) :: debug
call solve(f, fp, x0, x, iters, debug)
contains
real(r8) function f(x)
real(r8),intent(in) :: x
f = a * x * x + b * x + c
end
real(r8) function fp(x)
real(r8),intent(in) :: x
fp = 2 * a * x + b
end
end
end
这段代码的基本原理是:f
and fp
躺在里面的solve_quad
过程中,他们可以访问参数a
, b
and c
由主机关联,而不触及这些函数的签名。产生的效果就像改变函数的数量一样。
使用 gfortran 8.0 和solver
从您共享的链接实现,我得到了这个:
program test
use, intrinsic :: iso_fortran_env, only: r8 => real64
use :: without_custom_type
implicit none
real(r8) :: x, x0
integer :: iters
integer :: a = 1, b = -5, c = 4
x0 = 0
call solve_quad(a, b, c, x0, x, iters, .false.)
print *, x, iters
! output: 1.0000000000000000, 5
x0 = 7
call solve_quad(a, b, c, x0, x, iters, .false.)
print *, x, iters
! output: 4.0000000000000000, 6
end