与C不同,Fortran在每种情况下都不需要休息。但除了goto
之外,有没有办法跳出select case语句? (如果可能的话,我宁愿选择另一种方法来跳转,我也不能在select case语句中使用exit。)
select case(key)
case("cat")
if(value > 5) !break!
case("dog")
...
endselect
这是一个更详细的例子。虽然还有其他类型的流量控制,但在我看来,休息将是最好的
integer, allocatable :: Err(:)
select case(key)
case("cat")
if(value1 > 5) call PushBack(Err, 1001)
if(NotANumber(value2)) call PushBack(Err, 1002)
if(value3 /= "good") call PushBack(Err, 1003)
if(allocated(Err)) !break!
.... !some processing
case("dog")
....
endselect
if(allocated(Err)) call ShowError(key, Err)
如果我把所有东西放进去:
integer, allocatable :: Err(:)
select case(key)
case("cat")
if(value1 > 5) then !Here only one of the value1, value2... is checked
call PushBack(Err, 1001)
elseif(NotANumber(value2)) then
call PushBack(Err, 1002)
elseif(value3 /= "good") then
call PushBack(Err, 1003)
else
.... !some processing
case("dog")
....
endselect
if(allocated(Err)) call ShowError(key, Err)
如果有更好的解决方案,请告诉我。
答案 0 :(得分:7)
您在Fortran 2008中遇到了一项未在编译器中完全实现的改进。在Fortran 2008中,exit
可用于与do
循环以外的其他内容相关联。
我认为有三种方法有效:
case1: select case(key)
case("cat")
if (value > 5) exit case1
case("dog")
...
end select case1
这是Fortran 2008的方式。
case1: select case(key)
case("cat")
if (value > 5) goto 1 ! Let's pretend this is an exit: we'll have compiler
! support soon enough, and we can replace with exit
case("dog")
...
end select case1
1 continue
这是假的Fortran 2008方式。评论对这种方法至关重要。
massive_hack: do k=1,1
select case(key)
case("cat")
if (value > 5) exit massive_hack
case("dog")
...
end select case1
end do massive_hack
这是Fortran 2003 /讨厌goto
的方式。
对我来说,所有这些对于在案件中引入虚假的流量控制是更可取的。
说明:
Fortran 2003标准中exit
语句的措辞是:
EXIT语句提供了一种终止循环的方法。
...
EXIT语句属于特定的DO构造。如果EXIT语句引用DO构造名称,则它属于该DO构造;否则,它属于它出现的最里面的DO构造。
而Fortran 2008将其扩展为:
EXIT语句提供了一种终止循环或完成另一个构造的执行的方法。
...
EXIT语句属于特定构造。如果出现构造名称,则EXIT语句属于该构造;否则,它属于它出现的最里面的DO构造。
select case
构造是上面明确适用的构造。
Cursory glances建议当前版本的Cray,NAG,GCC和IBM编译器支持这种增强行为。
答案 1 :(得分:7)
扩展评论而不是回答......
我不明白@Francescalus为你解决的问题是什么。只有case
中的一个将被执行,到select case
结构的末尾的中断是Fortran的行为方式。在你的片段中:
select case(key)
case("cat")
if(value > 5) !break!
case("dog")
...
endselect
如果选择if(value > 5) !break!
,则仅执行第cat
行。如果你的片段应该是
select case(key)
case("cat")
if(value > 5) then
break
else
long and tedious processing
end if
case("dog")
...
endselect
嗯,这只是一种冗长的写作方式
select case(key)
case("cat")
if(value <= 5) then
long and tedious processing
end if
case("dog")
...
endselect
C及其同类中需要break
语句(或一些语法等价物),因为默认行为是在每个case
的末尾落实。
在我看来,@ Francescalus的massive_hack
绝对适用于Fortran 2008中的exit
,允许从封闭的do
结构退出以终止计算 - 重复循环一系列元素。
我希望我完全错过了这一点......
答案 2 :(得分:0)
我同意高性能标记,这种在开关盒内的这种中断(或退出)的构造需求在这里是有缺陷的。不仅在这个switch-case-construct中,而且对于所有人来说,总是可以通过简单地不执行该特定情况的其余部分来跳到最后。这最好通过一个if条件并进行&#34;额外处理&#34;代码进入if-block。
当然,多次这样做会增加缩进级别。但是像往常一样,如果发生这种情况,你可能最好将一些复杂性转移到子程序或函数中。
因此,EXIT和GOTO都不是一个好的答案。