存储a";指向函数的指针;用Fortran语言?
在Fortran中,您可以将一个函数/子例程a作为参数传递给另一个函数/子例程B,但是否可以存储a以供以后检索和使用 例如,这在C中是允许的存储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
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:尚未实现的功能:源=多态表达=(