【问题标题】:Fortran infinite loop when calling a function调用函数时的 Fortran 无限循环
【发布时间】:2023-03-22 23:58:01
【问题描述】:

为什么我会陷入无限循环?

PROGRAM tayls
  USE kertoma
  USE tforexp
  IMPLICIT NONE
  INTEGER :: n= 5
  INTEGER :: i
  REAL :: x
  WRITE(*,*) "f1(x)= (e**x-1)/x"
  DO i=1,10
    x= 0.01*i
    WRITE(*,*)x, (taylexp(x,n)-1)/x
  END DO
END PROGRAM tayls

MODULE tforexp
  USE kertoma
  IMPLICIT NONE
    CONTAINS
      FUNCTION taylexp(x,ord)
        REAL :: taylexp, x, sum
        INTEGER :: ord, i
        sum= 1.0
        DO i=1,ord
          sum= sum+ x**i/fact(i)
        END DO
        taylexp= sum
      END FUNCTION taylexp
END MODULE tforexp

MODULE kertoma
  IMPLICIT NONE
CONTAINS
  FUNCTION fact(n)
    INTEGER :: fact,n,y=1
    DO WHILE (n>1)
      y= y*n
      n= n-1
    END DO
    fact = y
  END FUNCTION fact
END MODULE kertoma

无限循环在第一次打印“f1(x)=...”之后立即开始。 所以我认为第一次调用 taylexp 函数时它会进入无限循环,但我不明白为什么。 我认为这与使用公共变量的fortran有关,但我不知道如何始终避免这种情况。 首先,我尝试在不定义 x 的情况下调用该函数,只使用“0.01*i”,我认为问题可能是该函数对虚拟索引使用了相同的名称,但显然它并没有解决问题。

【问题讨论】:

  • 我不知道这是否是问题所在,但请注意 integer :: y=1 可能是 doesn't do 你认为的那样。
  • taylerr 在哪里使用?那为什么会在帖子里呢?

标签: fortran infinite-loop fortran95


【解决方案1】:

问题出在函数fact(n)内部:

n= n-1

更改参数,因此更改taylexp 中的循环计数器i。在您的代码中i 永远不会超过2。我很惊讶编译器没有发出警告(我的也没有),因为在这种情况下可能会发生任何事情。

最好指定虚拟参数的intent 以避免将来出现此类问题:

  FUNCTION fact(n)
    integer,intent(in)  :: n
    INTEGER :: fact,nn,y

    y=1 ! Avoid the implicit save and assign variables separately
    nn=n
    DO WHILE (nn>1)
      y= y*nn
      nn= nn-1
    END DO
    fact = y
  END FUNCTION fact

【讨论】:

  • 或者甚至可能是integer, intent(in), value :: n,避免nn
  • @francescalus 是的,但我尝试一次解决一个问题 ;-)(除了隐式保存,它应该被标准禁止)
【解决方案2】:

使用 gfortran,可以使用 -fcheck=all 选项:

$ gfortran -fcheck=all 1.f90 
$ ./a.out
 f1(x)= (e**x-1)/x
At line 22 of file 1.f90
Fortran runtime error: Loop variable has been modified

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-09
    • 1970-01-01
    • 2018-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多