Fortran 访问例程位于单独例程中的“contains”语句内

Mar*_*rce 1 static fortran

我正在尝试重置例程内的保存变量,我理论上解决此问题的一种方法是使用一个将内部数据清零的重置()函数,但是我无法直接调用该函数,因为它位于“contains”关键字内,有没有办法超越这种保护?我研究了“接口”和“外部”关键字,但这个特定问题的文档似乎很少

program main
   implicit none

   call count ! 1
   call count ! 2
   call count ! 3

   ! cannot make a call to reset
   ! is there any way to remove this
   ! protection and access this directly?
   call reset
   call count ! 1 etc...
end program main

subroutine count
   integer, save :: numcalled = 0

   numcalled = numcalled + 1
   print *, numcalled

   return
contains

   subroutine reset
      numcalled = 0
   end subroutine reset
end subroutine count

Run Code Online (Sandbox Code Playgroud)

这是一个小例子,旨在了解我打算对带有一堆“保存”变量的项目执行什么操作,我需要重置这些变量,因为此代码将被调用多次,并且每个函数调用都需要新鲜的内容(没有处于不良状态的静态变量),如果我可以覆盖此保护以访问“contains”关键字内的子例程,这将是一项非常微创的任务

Vla*_*r F 5

之后声明的过程contains内部过程。外界无法调用它。不可能。

您必须将数据存储在模块中并具有重置模块程序

module subs
    implicit none

    integer, save :: numcalled = 0

contains

  subroutine count
   

    numcalled = numcalled + 1
    print *, numcalled

  end subroutine count

  subroutine reset
      numcalled = 0
  end subroutine reset
end module
Run Code Online (Sandbox Code Playgroud)

或者给你的count子例程一个特殊的参数来告诉它应该reset为你调用它的函数。

subroutine count(do_reset)
   integer, save :: numcalled = 0
   logical :: do_reset

   if (do_reset) call reset

   numcalled = numcalled + 1
   print *, numcalled

   return
contains

   subroutine reset
      numcalled = 0
   end subroutine reset
end subroutine count
Run Code Online (Sandbox Code Playgroud)

您可以将参数设置为可选。您也可以return在调用后从子例程中调用reset而不执行其余代码。

无论如何,无论您选择哪种解决方案,如果没有具体原因,所有过程都应该在模块中。