Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran 如何使作为参数传递的子例程名称在整个模块中可用?_Fortran_Arguments_Subroutine_Fortran95 - Fatal编程技术网

Fortran 如何使作为参数传递的子例程名称在整个模块中可用?

Fortran 如何使作为参数传递的子例程名称在整个模块中可用?,fortran,arguments,subroutine,fortran95,Fortran,Arguments,Subroutine,Fortran95,我希望使用一个变量子例程名称,并且我希望这个名称在整个模块中都可用,而不仅仅是在单个子例程中 作为参数传递的变量子例程名称是一种数据类型。它存放在哪里?我如何访问它 这里有更多的解释。G是一个非线性拟合程序。H使用G,但参数分组(迭代一次移动一个组)。G使用一个通用的正向模型子例程,其名称作为参数传递。我希望H保留这种普遍性 以下是使用带有硬编码子例程名称的变通方法的测试程序: module G_MOD implicit none character(len=30)::message

我希望使用一个变量子例程名称,并且我希望这个名称在整个模块中都可用,而不仅仅是在单个子例程中

作为参数传递的变量子例程名称是一种数据类型。它存放在哪里?我如何访问它

这里有更多的解释。G是一个非线性拟合程序。H使用G,但参数分组(迭代一次移动一个组)。G使用一个通用的正向模型子例程,其名称作为参数传递。我希望H保留这种普遍性

以下是使用带有硬编码子例程名称的变通方法的测试程序:

  module G_MOD
  implicit none
  character(len=30)::message='Good Morning'

  contains

  subroutine G(Sub)
  external::Sub
  call Sub
  end subroutine G

  end module G_MOD

  module H_MOD
  use G_MOD
  implicit none

  contains

  subroutine H(sub)
  external:: sub
  call G(LocalSub)
  end subroutine H

  subroutine LocalSub
  external:: MySub
  message='Good Afternoon'
  call G(MySub) ! the subroutine name "MySub" is hardcoded
                ! I would like it to be argument sub
  end subroutine LocalSub

  end module H_MOD

  program test
  use H_MOD
  implicit none
  external MySub
  call H(MySub)
  end program test

  subroutine MySub
  use G_MOD,only:message
  write(*,*)trim(Message)
  end subroutine MySub
解决方案1 如果将
LocalSub
设置为
H
内部,则无需存储任何内容:

  subroutine H(sub)
    external:: sub
    call G(LocalSub)
  contains
    subroutine LocalSub
      message='Good Afternoon'
      call G(sub)
    end subroutine LocalSub
  end subroutine H
它需要Fortran 2008

通过一些清理、缩进以提高可读性、使用抽象接口删除丑陋的外部(Fortran 2003,但即使在使用接口块的Fortran 90中也可以避免
external
),代码是:

  module G_MOD
    implicit none
    character(len=30)::message='Good Morning'

    abstract interface
      subroutine sub_interface
      end subroutine
    end interface

  contains

    subroutine G(Sub)
      procedure(sub_interface) :: sub
      call Sub
    end subroutine G

  end module G_MOD

  module H_MOD
    use G_MOD
    implicit none

  contains

    subroutine H(sub)
      procedure(sub_interface) :: sub
      call G(LocalSub)
    contains
      subroutine LocalSub

        message='Good Afternoon'
        call G(sub) 
      end subroutine LocalSub
    end subroutine H

  end module H_MOD

  program test
    use H_MOD
    implicit none


    call H(MySub)
  contains
    subroutine MySub
      use G_MOD,only:message
      write(*,*)trim(Message)
    end subroutine MySub
  end program test

解决方案2 如果您确实想在模块中存储对过程的引用,这是可能的,但请记住全局变量很难看。如果您想并行调用多个优化,该怎么办

因此,您可以将过程的地址(而不是名称)存储在
过程指针中。这些都需要Fortran 2003。对代码的最小更改是

  module H_MOD
    use G_MOD
    implicit none

    procedure, pointer :: stored_sub => null()

  contains

    subroutine H(sub)
      external:: sub
      stored_sub => sub
      call G(LocalSub)
    end subroutine H

    subroutine LocalSub
      message='Good Afternoon'
      call G(stored_sub)
    end subroutine LocalSub

  end module H_MOD
但更好的现代代码是:

  module G_MOD
    implicit none
    character(len=30)::message='Good Morning'

    abstract interface
      subroutine sub_interface
      end subroutine
    end interface

  contains

    subroutine G(Sub)
      procedure(sub_interface) :: sub
      call Sub
    end subroutine G

  end module G_MOD

  module H_MOD
    use G_MOD
    implicit none

    procedure(sub_interface), pointer :: stored_sub => null()

  contains

    subroutine H(sub)
      procedure(sub_interface) :: sub
      stored_sub => sub
      call G(LocalSub)

    end subroutine H

    subroutine LocalSub

      message='Good Afternoon'
      call G(stored_sub) 
    end subroutine LocalSub

  end module H_MOD


  module MySub_module
  contains
    subroutine MySub
      use G_MOD,only:message
      write(*,*)trim(Message)
    end subroutine MySub
  end module MySub_module

  program test
    use H_MOD
    use MySub_module
    implicit none


    call H(MySub)
  end program test
尽管如此,我还是更喜欢带有内部程序的变体


请记住,使用缩进,这对于可读代码至关重要。

对所有Fortran问题使用标记以引起更多注意。当您有模块时,不要使用外部标记。在Fortran 2003中有一些很好的方法。出于某种原因,您是否需要严格的旧Fortran 95?如果您修改它,可能会发生重复情况?修改的问题是在行调用G(存储的\u sub)之前添加行调用存储的\u sub。这应该功能相同,并产生两条“午安”消息。但是,它会导致G95的编译失败,而不会导致Intel(在文件解决方案2中)的编译失败。例如:36调用存储的\u sub 1错误:位于(1)的符号“存储的\u sub”没有隐式类型。G95中存在一些错误。忘记G95,它是旧的,不再受支持。请改用gfortran。