如何在Fortran中为函数起别名

35

不确定标题是否恰当,欢迎提出建议。

我想要做的是:检查一个条件,然后在循环中决定使用哪个函数。例如:

if (a < 0) then
    loop_func = func1
else
    loop_func = func2
endif
我可以使用loop_func作为指针来编写我的循环。这两个函数接受完全相同的输入,并且是根据a的值处理问题的不同方法。这将使我只有一个代码块,而不是两个几乎相同的代码块。这也可以应用于子程序。
有任何想法如何实现吗?
谢谢。
2个回答

45

是的,Fortran具有过程指针,因此您可以实际上给函数名取别名。以下是一个代码示例,该示例将一个函数分配给函数指针"f_ptr",然后程序可以使用"f_ptr"并调用所选的函数。

module ExampleFuncs

   implicit none

contains

function f1 (x)
  real :: f1
  real, intent (in) :: x

  f1 = 2.0 * x

  return
end function f1


function f2 (x)
   real :: f2
   real, intent (in) :: x

   f2 = 3.0 * x**2

   return
end function f2

end module ExampleFuncs


program test_func_ptrs

    use ExampleFuncs
    implicit none

   abstract interface
      function func (z)
         real :: func
         real, intent (in) :: z
      end function func
   end interface

   procedure (func), pointer :: f_ptr => null ()

   real :: input

   write (*, '( / "Input test value: ")', advance="no" )
   read (*, *) input

   if ( input < 0 ) then
      f_ptr => f1
   else
      f_ptr => f2
   end if

   write (*, '(/ "evaluate function: ", ES14.4 )' )  f_ptr (input)

   stop

end program test_func_ptrs

5
过程指针是Fortran 2003的一部分。自2008年中期以来,gfortran已经支持了它们--请参见http://gcc.gnu.org/wiki/Fortran2003和http://gcc.gnu.org/wiki/ProcedurePointers。 - M. S. B.
3
Fortran 2003有什么问题吗?gfortran使用过程/接口结构应该没有问题,对吧? - Samuel Tan
3
有哪些主要的编译器不支持过程指针?(不包括gcc、pgi、cray、IBM、NAG或intel)。还有谁被迫在其项目的每个文件中都使用F77 / F95? - Jonathan Dursi
2
@steabert:正在考虑的F2003特性是过程指针。哪个主要的编译器不支持过程指针? - Jonathan Dursi
2
@JonathanDursi:是的,你说得对,但我想表达的更为普遍。我真的不喜欢标准只被部分实现的事实,因为这使得“标准”的存在变得相当无用,实际上你必须去查找哪些功能是通常支持的,哪些不是。 - steabert
显示剩余6条评论

6
大多数Fortran实现没有一种标准的方法来操作函数指针或过程指针。 然而,从Fortran 2003版本开始有了一些改进。(请参见此文第6页。)对于给定的情况,这种方法将非常有效。
 function func1 (p1, p2, etc)
 ...  as you have it already
 end

 function func2 (p1, p2, etc)
 ...  as you have it already
 end

 function funcselect (a, p1, p2, etc)
     if (a < 0) then
          x = func1 (p1, p2, etc)
     else
          x = func2 (p1, p2, etc)
     endif
 end

那么现在只需要使用额外的参数调用funcselect,而不是使用loop_func


1
但是程序每次调用该函数时不需要检查条件吗?我想避免这种情况。 - Samuel Tan
4
我不同意"Fortran没有标准的方法来操作函数指针或过程指针"这个说法。过程指针是Fortran 2003语言标准的一部分。 - M. S. B.
2
@wallyk。在提问时,我将问题简化了一些。条件实际上不是(a<0),它要复杂得多。而且这不仅仅是一个简单的循环,函数将被用于多个循环中。为了让你有一个大致的了解,这个函数将会被调用超过800万次,每次迭代100次。 - Samuel Tan
3
如果你只是想利用函数指针进行优化,那么这种做法的效果值得怀疑,可能甚至会相反,具体取决于编译器优化和条件可预测性。 - Vladimir F Героям слава
3
原文:The OP stated that they wanted it for clarity and to avoid code duplication, both worthy goals; and using a function pointer allows them to avoid the code duplication without having the if statement deep in a loop, which is also a benefit.翻译:原帖作者指出他们想要这么做是为了增强代码的清晰度和避免重复编写代码,这两个目标都值得追求;而使用函数指针可以避免将if语句嵌套在循环深处以避免代码重复,这也是一个好处。 - Jonathan Dursi
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接