有什么方法可以将一组变量值通过子程序传递给没有公共块的函数?

时间:2015-09-03 22:02:24

标签: fortran fortran90 fortran77

我不想在程序中使用公共块。我的主程序调用一个调用函数的子程序。该函数需要子程序中的变量。

有什么方法可以将子程序中的信息集传递给函数?

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

3 个答案:

答案 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_Exampleres等可以在主程序块中使用值声明,并作为参数传递给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

这只是一个粗略的草图,但我得到的印象是你正在寻找的东西。