在Fortran中有条件地使用子例程

时间:2018-12-12 10:32:52

标签: fortran subroutine fortran95

我的情况:我想让我的Fortran(> = 95)程序基于参数选择计算中的两个子例程之一。例如,让我们有两个子例程foo,它们相减;和bar,将其两个整数参数相加。此外,我还有一个子例程callingsub,该子例程将foobar作为参数。完整程序可能看起来像

program choice

implicit none

integer :: a,b

a=3
b=4

call callingsub(a,b,foo)

contains

  subroutine foo(a,b,c)
    integer, intent(in) :: a,b
    integer, intent(out) :: c

    c=a-b
  end subroutine foo

  subroutine bar(a,b,c)
    integer, intent(in) :: a,b
    integer, intent(out) :: c

    c=a+b
  end subroutine bar

  subroutine callingsub(a,b,sub)
    integer, intent(in) :: a,b

    interface 
       subroutine sub(a,b,c)
         integer, intent(in) :: a,b
         integer, intent(out) :: c
       end subroutine sub
    end interface

    integer :: c

    call sub(a,b,c)
    write(*,*) 'Your answer is ',c
  end subroutine callingsub

end program choice

现在要在foobar之间切换,我必须重新编译,但是我宁愿在运行时选择。我想象有一个整数flag,如果0选择foo,而1选择bar,则整数。我当然可以写一个子程序

subroutine baz(a,b,c,flag)
  integer, intent(in) :: a,b
  integer, intent(out) :: c
  integer, intent(in) :: flag

  if (flag==0) then
    c=a-b
  else if (flag==1) then
    c=a+b
  else
    write(0,*) 'illegal flag ', flag
    stop 1
  end if
end subroutine baz

使用flag进行决定,但是,对callingsub的调用将陷入一个巨大的循环,我的感觉告诉我,最好对{{1 }}或foo

在主程序中是否有条件决定的可能性?我想像

bar

,然后是if (flag==0) then chosensub=foo elseif (flag==1) then chosensub=bar else !error and exit end if ,很遗憾,这是行不通的。我也无法将call callingsub(a,b,chosensub)置于条件中。

我对此表示感谢,并希望我说得足够清楚!

PS我可以访问Intel ifort 18.0.5 20180823,因此我不仅限于F95。

1 个答案:

答案 0 :(得分:4)

好吧,在遵循@ M.S.B的回答here之后,这是我的工作,以供将来参考,因此,感谢@HighPerformanceMark和@IanBush指向该方向(哈哈):

program choice

implicit none

integer :: a,b,flag

interface
   subroutine chosensub(a,b,c)
     integer, intent(in) :: a,b
     integer, intent(out) :: c
   end subroutine chosensub
end interface

procedure(chosensub), pointer :: subptr=>null()

read(*,*) flag

if (flag==0) then
   subptr=>foo
else if (flag==1) then
   subptr=>bar
else
   write(0,*) 'error message'
   stop 1
end if

a=3
b=4

call callingsub(a,b,subptr)

contains

! as in OP

end program choice