如何基于用户输入变量(fortran90)执行多条语句?
我正在写一个Fortran90子程序,但是语言对于这个问题来说并不重要。如果更方便的话,可以用psuedocode提供答案 我有许多语句(或语句组)要根据输入参数执行。让输入变量为如何基于用户输入变量(fortran90)执行多条语句?,fortran,fortran90,Fortran,Fortran90,我正在写一个Fortran90子程序,但是语言对于这个问题来说并不重要。如果更方便的话,可以用psuedocode提供答案 我有许多语句(或语句组)要根据输入参数执行。让输入变量为x,我们调用语句A、B、C、…、N。这些语句没有足够的公共属性进行组合,因此应该单独执行 条件是: if ( x .eq. 1 ) then ! execute A endif if ( x .eq. 2 ) then ! execute A ! execute B if ( x .eq. 3 ) then
x
,我们调用语句A、B、C、…、N。这些语句没有足够的公共属性进行组合,因此应该单独执行
条件是:
if ( x .eq. 1 ) then
! execute A
endif
if ( x .eq. 2 ) then
! execute A
! execute B
if ( x .eq. 3 ) then
! execute A
! execute B
! execute C
endif
.
.
.
等等
(请注意,所有的!execute
语句都是数学计算和变量赋值。不打印任何内容,也不调用任何函数,等等。)
我试图将代码简化为:
if ( x .ge. 1 ) then
! execute A
endif
if ( x .ge. 2 ) then
! execute B
endif
if ( x .ge. 3 ) then
! execute C
endif
.
.
.
对于较大的
x
,这仍然是太多的编码。我知道我必须对所有execute
语句进行编码(我已经这样做了),但我希望还有一种更快的方法,可以只运行用户指定的数字,而不必键入100多条if
语句。有什么想法吗?这不是一个理想的解决方案,因为F90没有函数指针。可以在F03中使用函数指针执行此操作,但由于您指定了F90
subroutine selector(howmany)
integer, intent(in):: howmany
integer:: ii
do ii = 1, howmany
select case(ii)
case (1)
! execute A
case (2)
! execute B
case (3)
! execute C
case default
continue
end select
end do
end subroutine selector
...
call selector(3)
与C不同,fortran没有下拉菜单,如果符合以下条件,您可以使用一行版本的
:
if ( x .ge. 1 ) call ... ! execute A
if ( x .ge. 2 ) call ... ! execute B
...
或者,如果在子例程
或函数
中处理,则可以使用返回
:
call ... ! execute A
if ( x .lt. 2 ) return
call ... ! execute B
if ( x .lt. 3 ) return
...
也可以在每条语句的一行中执行此操作:
call ... ; if ( x .lt. 2 ) return ! execute A
call ... ; if ( x .lt. 3 ) return ! execute B
我认为它不会比这少,即使在使用函数指针时,您也必须将它们指向相应的函数/子例程(每个函数也相当于一行).噢,computed go to
不受欢迎,真是太遗憾了。C21中没有一个自尊的Fortran程序员会写这样的东西
...
read(*,*) x
go to (3,2,1) x
1 call C()
2 call B()
3 call A()
当然,这会以与问题中指定的相反的顺序执行调用
,但问题也暗示顺序无关紧要
最后,我要提醒读者,这绝对是讨厌的旧FORTRAN。让我们不要再谈论这件事了我可能会这样做:
i=howmany
do while(i.gt.0)
< a code >
i=i-1;if(i.eq.0)exit
< b code >
i=i-1;if(i.eq.0)exit
<c code>
i=i-1;if(i.eq.0)exit
<d code>
exit
enddo
recursive subroutine select(x)
integer,intent(in) :: x
select case(x)
case(1)
!execute A
case(2)
!execute B
case(3)
!execute C
end select
if(x > 0) call select(x-1)
end subroutine select
i=有多少个
中途休息(i.gt.0)
i=i-1;如果(i.eq.0)退出
i=i-1;如果(i.eq.0)退出
i=i-1;如果(i.eq.0)退出
出口
结束循环
或者等效地使用带有返回的子例程
注意,这在逻辑上等同于您开始的位置,但条件行是相同的,因此懒惰的打字员可以快速执行ctrl-y ctrl-y ctrl-y
这样做的另一个优点是,如果需要编辑行,您可以在任何位置插入/删除行,而无需手动重新编制索引。递归子例程如何?大概是这样的:
i=howmany
do while(i.gt.0)
< a code >
i=i-1;if(i.eq.0)exit
< b code >
i=i-1;if(i.eq.0)exit
<c code>
i=i-1;if(i.eq.0)exit
<d code>
exit
enddo
recursive subroutine select(x)
integer,intent(in) :: x
select case(x)
case(1)
!execute A
case(2)
!execute B
case(3)
!execute C
end select
if(x > 0) call select(x-1)
end subroutine select
同样,这是向后的,但是向前的版本应该不会太难。如果你有很多这样的东西,总是有堆栈溢出的可能性。这实质上是在接受的答案中去掉显式循环。如果我理解正确,子例程将只对情况2执行B,对情况3执行C。我想要的是为案例2执行A和B,为案例3执行A、B和C,等等…@Timmy,这可以通过指定一个值范围轻松实现。如果应该对案例1到N执行语句X,请使用case(1:N)
。您可以使用更复杂的列表。请参阅此处的示例,其工作方式与此相同。ii上的循环选择a,然后选择b,以此类推。无论是do
循环还是:
操作符都可以完成。我可能遗漏了一些内容,但我不知道如何使用案例(1:n)
表单来实现这一点。如果有办法的话,应该有人来解决这个问题。现在的孩子们,用他们的“模块化”这个和“重新设计”那个,还有GUI、IDE和iPod。回到我们的时代,我们使用计算gotos,在8.5x14上打印出清单“绿吧,我们喜欢它+1这正是我想让程序做的。如果是个人项目,我会使用它,但我必须在这个项目上使用select case
,因为您提到的原因唯一的问题是,如果x是2,它执行B,然后执行a;如果x是3,它执行C,然后执行B,然后执行A。只有当A、B和C相互独立时,它才会工作。