首页 > 解决方案 > 现代 Fortran 等效于嵌套 DO 和 GO TO 共享的操作语句

问题描述

do我在我正在使用的旧代码中遇到了一个嵌套结构,并希望能够理解和现代化。它使用相同的标记操作语句来终止do循环,以及go to语句。这是一个简化版本,它通过一些其他微不足道的操作说明了原始代码的逻辑:

      subroutine original(lim)
      k=0
      do 10 i=1,4
        do 10 j=1,3
          k=k-2
          if (i>lim) go to 10
          k=k+i*j
 10   k=k+1
      write(*,*) k
      return
      end

在查看了本网站(和外部资源)上的其他问题 后,这是我重写原始代码逻辑的最大努力,没有过时的功能(和):go to

subroutine modern(lim)
  integer, intent(in) :: lim
  integer :: i, j, k
  k=0
  outer: do i=1,4
    inner: do j=1,3
      k=k-2
      if (i>lim) then
        k=k+1
        cycle inner
      end if
      k=k+i*j
      k=k+1
    end do inner
  end do outer
  write(*,*) k
end subroutine modern

我使用以下程序测试了代码,包括触发/不触发go to语句的替代方案:

  write(*, '(a)') 'original:'
  call original(2)
  call original(5)

  write(*, '(/,a)') 'modern:'
  call modern(2)
  call modern(5)
end

它为原始和我的现代重写给出了相同的结果:

original:
 6
 48

modern:
 6
 48

操作语句(对我来说)重写do循环很复杂,不能简单地用两个end do语句替换它,而go to. 我的重写需要复制操作语句(在inner循环结束时,在if 语句的主体内)。所以我的问题是:

标签: fortran

解决方案


您的original子例程肯定是 Fortran 标准在删除非块 DO 构造时所考虑的代码类型:

DO 循环的非阻塞形式令人困惑且难以维护。共享终止和标记操作语句的双重使用以及终止和分支目标特别容易出错。

如果我们有一个共享终止的非阻塞 DO,看起来像

do 1
  do 1
1 <action>

那么我们可以写出等价的

do 2
  do 1
    <action>
  1 end do
2 end do

(这里的标签可以去掉)

动作语句只需要编写一次,并且在最内层循环内。因为它是一个共享终止,执行它一次标志着每个共享它的 DO 构造的迭代结束。

如果我们从最里面的1结构分支到动作语句(with go to),比如

do 1
  do 1
    go to 1
1 <action>

我们有等价的

do 3
  do 2
    go to 1
    1 <action>
  2 end do
3 end do

我们通常的替换go to分支的策略是可用的。


让我们将其应用于原始循环(忽略相同效果的任何逻辑更改并使用冗余语句标签)

do 10 i=1,4
  do 10 j=1,3
    k=k-2
    if (i>lim) go to 10
    k=k+i*j
10 k=k+1

我们可以这样写

do 30 i=1,4
  do 20 j=1,3
    k=k-2
    if (i>lim) go to 10
    k=k+i*j
    10 k=k+1
  20 end do
30 end do

来到go to,我们有(至少这些)两种简单的方法。

否定 IF:

    if (i<=lim) k=k+i*j
    10 k=k+1

使用块:

    nogoto: block
      if (i>lim) exit nogoto
      k=k+i*j
    end block nogoto
    10 k=k+1

如您所见,“动作语句的重复”来自语句的使用cycle。在重写的循环中,您必须复制操作语句,因为您没有到达操作语句所在的循环末尾。原始循环没有 acycle并且循环会改变循环的行为(共享终止在循环时不执行,而是在 go-to 时执行)。


1如果分支不在最里面的构造中,情况肯定会更加复杂。为了清楚这个答案,我不会在这里讨论这种情况。


推荐阅读