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_Fortran90_Fortran95 - Fatal编程技术网

Fortran 多次调用子例程,每次使用不同的函数作为参数

Fortran 多次调用子例程,每次使用不同的函数作为参数,fortran,fortran90,fortran95,Fortran,Fortran90,Fortran95,我是个不懂术语的新手,所以我无法在网上搜索答案 在编程方面,我不止一次想做这样的事情 A和B是子程序,c和d是函数。A和B各自在其内部多次调用函数 call A(c(x)) call A(d(x)) call B(c(x)) call B(d(x)) 这个结构不起作用。我听说Fortran不支持函数的别名,至少在这种情况下是这样。(大多数涉及“别名”的搜索结果都是指别名变量而不是函数,这就是我没有找到答案的原因。) 那么,在不必编写多个版本的A和B的情况下,我可以使用什么样的结构来实现这一点呢

我是个不懂术语的新手,所以我无法在网上搜索答案

在编程方面,我不止一次想做这样的事情

A和B是子程序,c和d是函数。A和B各自在其内部多次调用函数

call A(c(x))
call A(d(x))
call B(c(x))
call B(d(x))
这个结构不起作用。我听说Fortran不支持函数的别名,至少在这种情况下是这样。(大多数涉及“别名”的搜索结果都是指别名变量而不是函数,这就是我没有找到答案的原因。)


那么,在不必编写多个版本的A和B的情况下,我可以使用什么样的结构来实现这一点呢?

我不完全确定我是否理解您想要的内容,但它是否类似于以下内容

Program f

  Implicit None

  Interface
     Integer Function c( x )
       Implicit None
       Integer, Intent( In ) :: x
     End Function c
     Integer Function d( x )
       Implicit None
       Integer, Intent( In ) :: x
     End Function d
  End Interface

  Call a( 3, c )
  Call a( 4, d )

  Call b( 5, c )
  Call b( 6, d )

Contains

  Subroutine a( x, func )

    Integer, Intent( In ) :: x
    Interface
       Integer Function func( x )
         Implicit None
         Integer, Intent( In ) :: x
       End Function func
    End Interface

    Write( *, * ) 'In a. Func = ', func( x )

  End Subroutine a

  Subroutine b( x, func )

    Integer, Intent( In ) :: x
    Interface
       Integer Function func( x )
         Implicit None
         Integer, Intent( In ) :: x
       End Function func
    End Interface

    Write( *, * ) 'In b. Func = ', func( x )

  End Subroutine b

End Program f

Integer Function c( x )
  Implicit None
  Integer, Intent( In ) :: x
  c = 2 * x
End Function c

Integer Function d( x )
  Implicit None
  Integer, Intent( In ) :: x
  d = 10 * x
End Function d
Wot now? gfortran -std=f95 f.f90 
Wot now? ./a.out
 In a. Func =            6
 In a. Func =           40
 In b. Func =           10
 In b. Func =           60
Wot now? 
另一种选择是过程指针,但您需要一个f2003编译器来实现这一点,而且这些编译器还不太常见-上面的代码可以返回到f90,甚至更早,外部代码可以执行您想要的操作,但是错误检查功能更少

调用a(c(x))看起来像是计算c(x)并将其传递给子例程a,正如伊恩在评论中所说

如果您想将一个函数“C”传递给子例程a,该函数接受一个类型为X的参数,有几种方法可以做到这一点

如前所述,过程指针是一种新的方法。虽然支持所有Fortran 2003标准的编译器非常少,但这一部分得到了广泛支持

下面是一个改编自

调用“callfancy(f_ptr,2.0,answer)”看起来是一样的,但是通过更改函数指针f_ptr指向的函数,将不同的函数传递给子例程fancy


这与gfortran(版本4.4到4.7)和ifort一起编译。

我认为M.S.B.的回答描述了函数别名的含义;Fortran术语是“过程指针”。作为这一点和Ian答案的替代方法,您还可以使用过程伪参数(不一定是指针)。请注意,任何
过程
声明仅在2003年以后才受支持,但gfortran 4.7和ifort 13都支持这一点。可以使用或不使用(抽象)接口块:

module dummy_procedure
  implicit none

  abstract interface
    real function myfunc(x)
      real, intent(in) :: x
    end function
  end interface

contains      
  subroutine a(func)
    ! Using the interface block:
    procedure(myfunc) :: func         
    print*, 'a:', func(.5)
  end subroutine

  subroutine b(func)
    ! Using the explicit interface of a known procedure:
    procedure(f1) :: func  
    print*, 'b:', func(.5)
  end subroutine

  real function f1(x)
    real, intent(in) :: x
    f1 = 2.0 * x
  end function

  real function f2(x)
    real, intent(in) :: x
    f2 = 3.0 * x**2
  end function
end module
现在,您可以将
f1
f2
直接传递到
a
b
,输出如预期:

program main
  use dummy_procedure
  call a(f1)  ! a: 1.0
  call a(f2)  ! a: 0.75
  call b(f1)  ! b: 1.0
  call b(f2)  ! b: 0.75
end program

如果我明白你想做什么:

1) 在模块中定义函数

2) 使用模块

3) 将函数和输入数据作为单独的参数提供给子例程

下面是一个对我有用的代码:

module iterfuncs
contains

! two example functions:
function approach_golden_ratio(a) result(agr)
  agr=1./a+1.
end function approach_golden_ratio

function approach_other_ratio(a) result(aor)
  aor=1./(a-1)
end function approach_other_ratio

end module



program use_some_functions

use iterfuncs

real :: final_res

final_res=2.3
! call subroutine with 1st function
call iterate(final_res,approach_golden_ratio)
print *,final_res

final_res=2.3
! call subroutine with 2nd function
call iterate(final_res,approach_other_ratio)
print *,final_res

end program



subroutine iterate(res,func)

use iterfuncs

do n=1,100
  res=func(res)
enddo

return

end subroutine
您是否在问“如何将函数传递给过程?”(与将函数求值结果传递给过程相反,您的示例代码显示了这一点。)
module iterfuncs
contains

! two example functions:
function approach_golden_ratio(a) result(agr)
  agr=1./a+1.
end function approach_golden_ratio

function approach_other_ratio(a) result(aor)
  aor=1./(a-1)
end function approach_other_ratio

end module



program use_some_functions

use iterfuncs

real :: final_res

final_res=2.3
! call subroutine with 1st function
call iterate(final_res,approach_golden_ratio)
print *,final_res

final_res=2.3
! call subroutine with 2nd function
call iterate(final_res,approach_other_ratio)
print *,final_res

end program



subroutine iterate(res,func)

use iterfuncs

do n=1,100
  res=func(res)
enddo

return

end subroutine