从SELECT CASE中断

时间:2014-09-05 00:06:57

标签: select fortran case break

与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)

如果有更好的解决方案,请告诉我。

3 个答案:

答案 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都不是一个好的答案。