Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.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_Subroutine_Fortran95 - Fatal编程技术网

Fortran中子程序的有条件使用

Fortran中子程序的有条件使用,fortran,subroutine,fortran95,Fortran,Subroutine,Fortran95,我的场景:我想让我的Fortran>=95程序根据一个参数在计算中从两个子例程中选择一个。例如,我们有两个子例程foo,它进行减法运算;和bar,它添加了两个整数参数。此外,我还有一个名为sub的子程序,它以foo或bar作为参数。完整的程序可能看起来像 program choice implicit none integer :: a,b a=3 b=4 call callingsub(a,b,foo) contains subroutine foo(a,b,c) in

我的场景:我想让我的Fortran>=95程序根据一个参数在计算中从两个子例程中选择一个。例如,我们有两个子例程foo,它进行减法运算;和bar,它添加了两个整数参数。此外,我还有一个名为sub的子程序,它以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之间切换,我必须重新编译,但我宁愿在运行时进行选择。我想象有一个整数标志,如果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
它使用标志来决定,然而,调用callingsub将在一个巨大的循环中,我的感觉告诉我,最好在循环之前决定foo或bar

是否有可能在主程序中有一个条件来决定?我想象一下

if (flag==0) then
  chosensub=foo
elseif (flag==1) then
  chosensub=bar
else
  !error and exit
end if
然后打电话给callingsuba,b,chosensub,不幸的是这不起作用。我也不能将接口放入条件中

我很感激在这方面的任何帮助,希望我说得足够清楚


PS我有权访问英特尔ifort 18.0.5 20180823,因此我不限于F95。

好的,以下是我在@M.S.B.的回答之后所做的,以供将来参考,因此感谢@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

看看这两条快速且非常有用的评论,我甚至没有想到任何类型的指针,更不用说指向方法的可能性了……如果执行性能是您的目标,您是否计算了基于整数标志的原始方法分支与此指针方法之间的时间差?您可能更喜欢使用过程指针还有其他原因,但您可能会发现它执行速度较慢。使用整型标志方法时,预期的指令流对编译器更为可见,使用指针方法时,编译器必须足够聪明,以便将指针分配与后面的调用连接起来。结果将非常依赖于编译器和问题。