Условное использование подпрограмм в Фортране - PullRequest
0 голосов
/ 12 декабря 2018

Мой сценарий: я бы хотел, чтобы моя программа на Фортране (> = 95) выбрала одну из двух подпрограмм в расчете на основе параметра.В качестве примера, давайте иметь две подпрограммы, foo, которые вычитают;и bar, который добавляет два целочисленных аргумента.Кроме того, у меня есть подпрограмма callingsub, которая получает либо foo, либо bar в качестве аргумента.Полная программа может выглядеть как

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

Теперь для переключения между foo и bar мне нужно перекомпилировать, но я бы предпочел выбор во время выполнения.Я представляю себе целое число flag, которое, если 0 выбирает foo и если 1 выбирает бар.Конечно, я мог бы написать подпрограмму

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 будет в огромном цикле, и мое чувство подсказывает мне, что это будетЛучше иметь решение о 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), что, к сожалению, не работает.Я также не могу поставить interface s в условное выражение.

Я ценю любую помощь по этому вопросу и надеюсь, что я достаточно ясно дал понять!

PS У меня есть доступ к Intel ifort 18.0.5 20180823поэтому я не ограничен F95.

1 Ответ

0 голосов
/ 12 декабря 2018

ОК, для дальнейшего использования вот что я сделал, после ответа @MSB s здесь , поэтому спасибо @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
...