存储a";指向函数的指针;用Fortran语言?

存储a";指向函数的指针;用Fortran语言?,fortran,function-pointers,Fortran,Function Pointers,在Fortran中,您可以将一个函数/子例程a作为参数传递给另一个函数/子例程B,但是否可以存储a以供以后检索和使用 例如,这在C中是允许的 int foo(float, char, char) { /*whatever*/}; int (*pointerToFunction)(float, char, char); pointerToFunction = foo; 在Fortran中,可以将子例程作为参数传递 subroutine foo ! whatever end subroutine

在Fortran中,您可以将一个函数/子例程a作为参数传递给另一个函数/子例程B,但是否可以存储a以供以后检索和使用

例如,这在C中是允许的

int foo(float, char, char) { /*whatever*/};

int (*pointerToFunction)(float, char, char);
pointerToFunction = foo;
在Fortran中,可以将子例程作为参数传递

subroutine foo
! whatever
end subroutine foo

subroutine bar(func)
    call func
end subroutine bar

program x

    call bar(foo)

end program
但是,如何以与C语言类似的方式存储foo地址呢?

从所谓的“Fortran 2003”(ISO/IEC 1539-2004)开始,过程指针是Fortran语言的一部分。这无疑是Fortran语言的主要新特性之一

来自Fortran Wiki的用法


Stefano,你提到了战略设计模式。在Fortran 2003中,您可以使用纯OOP方式来实现它(无过程指针)。随便举个例子:

战略f90

module strategies

  implicit none

  private

  public :: strategies_transportation_strategy, &
            strategies_by_taxi_strategy, &
            strategies_by_bus_strategy

  type, abstract :: strategies_transportation_strategy
  contains
    procedure(transportation_strategy_go), deferred :: go
  end type strategies_transportation_strategy

  type, extends(strategies_transportation_strategy) :: strategies_by_taxi_strategy
  contains
    procedure :: go => strategies_by_taxi_strategy_go
  end type strategies_by_taxi_strategy

  type, extends(strategies_transportation_strategy) :: strategies_by_bus_strategy
  contains
    procedure :: go => strategies_by_bus_strategy_go
  end type strategies_by_bus_strategy

  abstract interface
    subroutine transportation_strategy_go(this)
      import strategies_transportation_strategy
      class(strategies_transportation_strategy), intent(in) :: this
    end subroutine transportation_strategy_go
  end interface

  contains

    subroutine strategies_by_taxi_strategy_go(this)
      class(strategies_by_taxi_strategy), intent(in) :: this

      print *, "We are using taxi."

    end subroutine strategies_by_taxi_strategy_go

    subroutine strategies_by_bus_strategy_go(this)
      class(strategies_by_bus_strategy), intent(in) :: this

      print *, "We are using public transport."

    end subroutine strategies_by_bus_strategy_go

end module strategies
车辆.f90

module vehicles

  use strategies

  implicit none

  private

  public :: vehicles_vehicle, &
            vehicles_taxi, &
            vehicles_bus

  type, abstract :: vehicles_vehicle
    private
    class(strategies_transportation_strategy), allocatable :: transportation_strategy
  contains
    procedure :: set_transportation_strategy => vehicle_set_transportation_strategy
    procedure :: go => vehicle_go
  end type vehicles_vehicle

  type, extends(vehicles_vehicle) :: vehicles_taxi
  contains
    procedure :: init => taxi_init
  end type vehicles_taxi

  type, extends(vehicles_vehicle) :: vehicles_bus
  contains
    procedure :: init => bus_init
  end type vehicles_bus

  contains

    subroutine vehicle_go(this)
      class(vehicles_vehicle), intent(in) :: this

      call this%transportation_strategy%go()

    end subroutine vehicle_go

    subroutine vehicle_set_transportation_strategy(this, new_transportation_strategy)
      class(vehicles_vehicle), intent(inout) :: this
      class(strategies_transportation_strategy), intent(in) :: new_transportation_strategy

      if (allocated(this%transportation_strategy)) then
        deallocate (this%transportation_strategy)
      end if

      allocate (this%transportation_strategy, source=new_transportation_strategy)

    end subroutine vehicle_set_transportation_strategy

    subroutine taxi_init(this)
      class(vehicles_taxi), intent(out) :: this

      type(strategies_by_taxi_strategy) :: by_taxi_strategy

      call this%set_transportation_strategy(by_taxi_strategy)

    end subroutine taxi_init

    subroutine bus_init(this)
      class(vehicles_bus), intent(out) :: this

      type(strategies_by_bus_strategy) :: by_bus_strategy

      call this%set_transportation_strategy(by_bus_strategy)

    end subroutine bus_init

end module vehicles
main.f90

program main

  use vehicles

  implicit none

  type(vehicles_taxi) :: taxi
  type(vehicles_bus) :: bus

  call taxi%init()
  call bus%init()

  call taxi%go()
  call bus%go()

end program main

至少可以使用gfortran 4.6(20100925)工作。

以下是演示如何使用过程指针的简短代码:

module my_mod
  implicit none
contains
  subroutine sub1()
    write(*,*) 'the first suboutine is being used'
  end subroutine sub1

  subroutine sub2()
    write(*,*) 'the second subroutine is being used'
  end subroutine sub2

end module my_mod

program procTest
  use my_mod
  implicit none                                             
  integer :: n
  procedure(sub1), pointer:: funPointer => NULL()
  write(*,'(A)') "Please enter your option"
  read(*,*) n                                                                  
  select case( n )
  case( 1 )
     funPointer => sub1
  case( 2 )
     funPointer => sub2
  case DEFAULT
     funPointer => sub1
  end select
  call funPointer()
end program procTest

你能不能解释清楚你想要什么,你想做什么?(特别是后者)@Rook:存储指向函数的指针。在C中,这是trivial@Stefano-不,据我所知不是。但话说回来,我不熟悉C指针。你能给我举个例子说明你为什么需要它吗?@Rook在fortran@Stefano-对不起,我不知道那意味着什么-甚至是一点点。但我很确定这不是一种错误的方式(在fortran中使用C的思维方式,反之亦然,几乎总是一种错误的方式),或者是一种在fortran中根本不常用的方式。可能是两者的混合。我很担心。好吧,我可以接受。我觉得ifort也支持它。@Stefano:我会在晚上检查ifort。是的,我是CTCC奥斯陆大学的博士生。但是,我做了一些质谱和量子化学计算,与道尔顿无关。ifort 11.1 20100203:vehicles.f90(48):错误35; 5415:尚未实现的功能:源=多态表达=(