1

我的程序中有一个do while循环,谁有条件继续给我一个错误,我不知道为什么。它看起来像这样:

do while (ii .le. nri .and. ed(ii) .le. e1)
    ! do some stuff...
    ii = ii + 1
end do

其中iinri是标量整数,e1是标量实数,并且ed是长度为的实数数组nri。我期望在最后一次运行后发生的是,因为ii.le.nri返回.false.第二个条件从未被测试过,而且我没有遇到任何不合时宜的问题。我已经用确实返回的调试器进行了验证ii.le.nri-但程序.false.崩溃了。

为了验证我只测试一个条件的假设,我什至编写了一个小测试程序,我使用相同的编译器选项编译它:

 program iftest
     implicit none

     if (returns_false() .and. returns_true()) then
         print *, "in if block"
     end if
 contains
     function returns_true()
         implicit none
         logical returns_true
         print *, "in returns true"
         returns_true = .true.
     end function

     function returns_false()
         implicit none
         logical returns_false
         print *, "in returns false"
         returns_false = .false
     end function
 end program

正如我所料,运行此程序仅输出

 $ ./iftest
 in returns false

并退出。第二个测试永远不会运行。

为什么这不适用于我的do while条款?

4

2 回答 2

7

与某些语言相比,Fortran 不保证复合逻辑表达式的任何特定求值顺序。就您的代码而言,最后一次循环 while 循环的值ii设置为nri+1。您的编译器生成测试代码ed(nri+1)<=e1并因此引用ed. 这很可能是您的程序崩溃的原因。

您的期望与该语言的 Fortran 标准规定相反。

如果您还没有这样做,请尝试在打开数组边界检查的情况下重新编译您的代码,看看会发生什么。

至于为什么您的测试没有解决这个问题,我怀疑您的所有测试真正显示的是您的编译器为不同的条件种类生成了不同的执行顺序,并且您并没有真正比较同类。

于 2013-04-22T18:07:30.517 回答
4

扩展答案高性能标记,这是重写循环的一种方法:

ii_loop: do

  if (ii .gt. nri) exit ii_loop
  if (ed(ii) .gt. e1) exit ii_loop

  ! do some stuff

  ii = ii + 1

end do ii_loop
于 2013-04-22T18:36:06.980 回答