我不想在程序中使用公共块。我的主程序调用一个调用函数的子程序。该函数需要子程序中的变量。
有什么方法可以将子程序中的信息集传递给函数?
program
...
call CONDAT(i,j)
end program
SUBROUTINE CONDAT(i,j)
common /contact/ iab11,iab22,xx2,yy2,zz2
common /ellip/ b1,c1,f1,g1,h1,d1,b2,c2,f2,g2,h2,p2,q2,r2,d2
call function f(x)
RETURN
END
function f(x)
common /contact/ iab11,iab22,xx2,yy2,zz2
common /ellip/ b1,c1,f1,g1,h1,d1,b2,c2,f2,g2,h2,p2,q2,r2,d2
end
答案 0 :(得分:6)
您关心的是关联:您希望能够将函数f
中的实体与子例程condat
中的实体相关联。存储关联是执行此操作的一种方式,这是公共块正在执行的操作。
还有其他形式的关联可能有用。这些是
haraldkl's answer中描述了参数关联。
使用关联来自
等模块module global_variables
implicit none ! I'm guessing on declarations, but that's not important
public ! Which is the default
real b1,c1,f1,g1,h1,d1,b2,c2,f2,g2,h2,p2,q2,r2,d2,xx2,yy2,zz2
integer iab11,iab22
end module
subroutine condat(i,j)
use global_variables ! Those public things are use associated
...
end subroutine
function f(x)
use global_variables ! And the same entities are accessible here
...
end function
主机关联可以访问主机可访问的实体。这里的主机可以有用地作为模块或程序
module everything
integer iab11,...
real ...
contains
subroutine condat(i,j)
! iab11 available from the host module
end subroutine
function f(x)
! iab11 available from the host module
end function
end module
甚至子程序本身
subroutine condat(i,j)
integer iab11,...
real ...
contains
function f(x)
! Host condat's iab11 is accessible here
end function
end subroutine
答案 1 :(得分:3)
下面是一个如何实现这个目标的例子......
代码已经从BFGS方法改编而来,以展示如何传递函数并调用模块中的其他函数......
我在这里使用:
希望这能涵盖一切......
false
Module Mod_Example
Private :: private_func
SUBROUTINE test_routine(res,start,fin,vector,func,dfunc)
IMPLICIT NONE
REAL, DIMENSION(:), INTENT(IN) :: res, start, fin
REAL, DIMENSION(:), INTENT(INOUT) :: vector
INTERFACE
FUNCTION func(vector)
IMPLICIT NONE
REAL, DIMENSION(:), INTENT(IN) :: vector
REAL :: func
END FUNCTION func
FUNCTION dfunc(vector)
IMPLICIT NONE
REAL, DIMENSION(:), INTENT(IN) :: vector
REAL, DIMENSION(size(vector)) :: dfunc
END FUNCTION dfunc
END INTERFACE
! do stuff with p
private_func(res,start,fin,vector,func,dfunc)
! do stuff
END SUBROUTINE test_routine
SUBROUTINE private_func(res,start,fin,vector,func,dfunc)
IMPLICIT NONE
REAL, DIMENSION(:), INTENT(IN) :: res, start, fin
REAL, DIMENSION(:), INTENT(INOUT) :: vector
INTERFACE
FUNCTION func(vector)
REAL, DIMENSION(:), INTENT(IN) :: vector
REAL :: func
END FUNCTION func
FUNCTION dfunc(vector)
REAL, DIMENSION(:), INTENT(IN) :: vector
REAL, DIMENSION(size(vector)) :: dfunc
END FUNCTION dfunc
END INTERFACE
! do stuff
END SUBROUTINE private_func
END Mod_Example
和func
将在使用dfunc
的程序代码中声明,顶部有一个接口块。MODULE Mod_Example
,res
等可以在主程序块中使用值声明,并作为参数传递给start
。SUBROUTINE test_routine
会使用传递给它的变量调用SUBROUTINE test_routine
。您的主程序看起来像这样:
private_func
答案 2 :(得分:3)
所以,基本上你可以用这些方法解决这个问题:
SUBROUTINE CONDACT(i,j, iab11,iab22,xx2,yy2,zz2,b1,c1,f1,g1,h1,d1,b2,c2,f2,g2,h2,p2,q2,r2,d2,res)
!declaration to all those parameters and res
res = f(x)
END SUBROUTINE CONDACT
function f(x,iab11,iab22,xx2,yy2,zz2,b1,c1,f1,g1,h1,d1,b2,c2,f2,g2,h2,p2,q2,r2,d2)
!declaration to all those parameters
end function f
program
...
call CONDAT(i,j,iab11,iab22,xx2,yy2,zz2,b1,c1,f1,g1,h1,d1,b2,c2,f2,g2,h2,p2,q2,r2,d2,res)
end program
也就是说,只需传递参数即可。 强烈建议使用模块,请参阅Alexander McFarlane的答案,尽管不是必需的。 Alexander McFarlane展示了如何将f作为参数传递给子例程,这样您就可以在子例程中使用不同的函数,但是您的代码似乎并不需要这样。
现在,这是一个非常长的参数列表,你可能不想随时携带这些参数。 解决这个问题的常用方法是将这些参数放入derived datatype,然后将其传递给它。 像这样:
!> A module implementing ellip related stuff.
module ellip_module
implicit none
type ellip_type
!whatever datatypes these need to be...
integer :: b1,c1,f1,g1,h1,d1,b2,c2,f2,g2,h2,p2,q2,r2,d2
end type
end module ellip_module
!> A module implementing condact related stuff.
module condact_module
use ellip_module ! Make use of the ellip module to have the type available
implicit none
type condact_type
!whatever datatypes these need to be...
integer :: iab11,iab22,xx2,yy2,zz2
end type
contains
subroutine condact(i,j, con, ellip, res)
integer :: i,j
type(condact_type) :: con
type(ellip_type) :: ellip
real :: res
real :: x
res = f(x, con, ellip)
end subroutine condact
function f(x, con, ellip) result(res)
real :: x
real :: res
type(condact_type) :: con
type(ellip_type) :: ellip
res = !whatever this should do
end function f
end module condact_module
!> A program using the condact functionality.
program test_condact
use ellip_module
use condact_module
implicit none
type(condact_type) :: mycon
type(ellip_type) :: myellip
integer :: i,j
real :: res
call condact(i,j, mycon, myellip, res)
end program test_condact
这只是一个粗略的草图,但我得到的印象是你正在寻找的东西。