从SELECT CASE中断

For*_*Cpp 6 select fortran case break

与C不同,Fortran在每种情况下都不需要休息.但有没有办法跳出选择案例陈述goto?(如果可能的话,我宁愿选择其他方式跳转,我也不能在select case语句中使用exit.)

select case(key)
case("cat")
    if(value > 5) !break!
case("dog")
...
endselect
Run Code Online (Sandbox Code Playgroud)

这是一个更详细的例子.虽然还有其他类型的流量控制,但在我看来,休息将是最好的

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)
Run Code Online (Sandbox Code Playgroud)

如果我把所有东西放进去:

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)
Run Code Online (Sandbox Code Playgroud)

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

fra*_*lus 7

您遇到了Fortran 2008中引入的改进,但未在编译器中完全实现.在Fortran 2008 exit中,可以使用与do循环之外的东西相关的东西.

我认为有三种方法有效:

case1: select case(key)
case("cat")
  if (value > 5) exit case1
case("dog")
...
end select case1
Run Code Online (Sandbox Code Playgroud)

这是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
Run Code Online (Sandbox Code Playgroud)

这是假的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
Run Code Online (Sandbox Code Playgroud)

这是Fortran 2003/hating goto的方式.

对我来说,所有这些对于在案例中引入虚假流量控制是更可取的.


说明:

exit声明的Fortran 2003标准中的措辞是:

EXIT语句提供了一种终止循环的方法.

...

EXIT语句属于特定的DO构造.如果EXIT语句引用DO构造名称,则它属于该DO构造; 否则,它属于它出现的最里面的DO构造.

而Fortran 2008扩展了以下内容:

EXIT语句提供了一种终止循环或完成另一个构造的执行的方法.

...

EXIT语句属于特定构造.如果出现构造名称,则EXIT语句属于该构造; 否则,它属于它出现的最里面的DO构造.

select case构造是上面明确适用的构造.

粗略的一瞥表明当前版本的Cray,NAG,GCC和IBM编译器都支持这种增强的行为.


Hig*_*ark 7

扩展评论而不是回答......

我不明白@Francescalus为你解决了什么问题.只有一个cases将被执行,到select case结构末尾的中断是Fortran的行为方式.在你的片段中:

select case(key)
case("cat")
    if(value > 5) !break!
case("dog")
...
endselect
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

那只是一种冗长的写作方式

select case(key)
case("cat")
    if(value <= 5) then
        long and tedious processing
    end if
case("dog")
...
endselect
Run Code Online (Sandbox Code Playgroud)

break声明(或一些语法等价物)需要在C及其之流,因为默认行为是在每年年底告吹case.

在我看来,@ Francescalus massive_hackexitFortran 2008中绝对合适的用法,它允许从一个封闭的do构造中退出,以终止一系列元素上的计算量很大的循环.

我希望我完全错过了这一点......