块 DO 构造

do 构造是循环构造,其具有由循环控制控制的多个迭代

integer i
do i=1, 5
  print *, i
end do
print *, i

在上面的形式中,循环变量 i 通过循环 5 次,依次取值 1 到 5。构造完成后,循环变量的值为 6,也就是说,循环变量在循环完成后再次递增

更一般地,do 环构造可以理解如下

integer i, first, last, step
do i=first, last, step
end do

循环以 i 开始,值为 first,每次迭代递增 step 直到 i 大于 last(或者如果步长为负,则小于 last)。

值得注意的是,自 Fortran 95 以来,循环变量和循环控制表达式必须是整数。

可以使用 cycle 语句提前结束迭代

do i=1, 5
  if (i==4) cycle
end do

并且整个构造可以用 exit 语句停止执行

do i=1, 5
  if (i==4) exit
end do
print *, i

do 结构可能被命名为:

do_name: do i=1, 5
end do do_name

这在嵌套的 do 构造时特别有用

do1: do i=1, 5
  do j=1,6
    if (j==3) cycle        ! This cycles the j construct
    if (j==4) cycle        ! This cycles the j construct
    if (i+j==7) cycle do1  ! This cycles the i construct
    if (i*j==15) exit do1  ! This exits the i construct
  end do
end do1

do 构造也可以具有不确定的循环控制,永远或直到满足给定条件

integer::i=0
do
  i=i+1
  if (i==5) exit
end do

要么

integer::i=0
do while (i<6)
  i=i+1
end do

这也允许通过 .true. 语句进行无限的 do 循环

print *,'forever'
do while(.true.)
  print *,'and ever'
end do

do 构造也可能使迭代次序不确定

do concurrent (i=1:5)
end do

注意到循环控制的形式与 forall 控件中的相同。

对于可以在 do concurrent 构造的范围内执行的语句存在各种限制,这些语句旨在确保构造的迭代之间不存在数据依赖性。程序员的这种明确指示可以使编译器能够进行更大的优化(包括并行化),否则可能难以确定。

通过在 do concurrent 中使用 block 构造,可以实现交互中的私有变量:

do concurrent (i=1:5, j=2:7)
  block
    real tempval  ! This is independent across iterations
  end block
end do

do 构造的另一种形式使用标记的 continue 语句而不是 end do

    do 100, i=1, 5
100 continue

甚至可以使用共享终止语句来嵌套此类构造

    do 100, i=1,5
    do 100, j=1,5
100 continue

为了清楚起见,通常应避免这两种形式,尤其是第二种形式(过时的)。

最后,还有一个非阻塞的 do 结构。这也被认为是过时的并且在别处描述 ,以及作为块 do 构建体重构的方法。