如何在while循环中更改fortran程序索引变量?

如何在while循环中更改fortran程序索引变量?,fortran,fortran95,Fortran,Fortran95,我有以下代码: PROGRAM PEU72 USE PRIMES IMPLICIT NONE INTEGER, PARAMETER :: MYKIND = SELECTED_INT_KIND(16) INTEGER (KIND=MYKIND) :: SOFAR INTEGER :: NRP, M SOFAR = 0_MYKIND CALL GEN(ALLNUMS,ALLPRIMES) ! This is a call to a module that creates a list of pr

我有以下代码:

PROGRAM PEU72
USE PRIMES
IMPLICIT NONE
INTEGER, PARAMETER :: MYKIND = SELECTED_INT_KIND(16)
INTEGER (KIND=MYKIND) :: SOFAR
INTEGER :: NRP, M

SOFAR = 0_MYKIND

CALL GEN(ALLNUMS,ALLPRIMES) ! This is a call to a module that creates a list of primes. It works fine.

DO M = 2,8  ! When I try to compile in G95, this loop doesn't increment. M = 2 for each cycle.
  SOFAR = SOFAR + NRP(M)
END DO

PRINT *,'ANS: ',SOFAR
READ *,SOFAR

END PROGRAM PEU72

FUNCTION NRP(NUM) RESULT(PHI)
USE PRIMES
IMPLICIT NONE
INTEGER :: NUM, PHI, I!, DIF
INTEGER :: VAR
I = 1
PHI = NUM-1
VAR = NUM
DO
  IF (MOD(NUM,ALLPRIMES(I))==0) THEN
    PHI = PHI-((NUM-1)/ALLPRIMES(I))
    NUM = NUM/ALLPRIMES(I) ! This is the line that silverfrost doesn't like. The code works absolutely fine without it, it just takes too long.
  END IF
  I = I + 1
  VAR = NUM-ALLPRIMES(I)
  IF (VAR<0) THEN
    EXIT
  END IF
END DO
RETURN
END FUNCTION
程序PEU72
使用素数
隐式无
整数,参数::MYKIND=所选类型(16)
整数(种类=MYKIND)::SOFAR
整数::NRP,M
SOFAR=0_MYKIND
呼叫GEN(ALLNUMS,ALLPRIMES)!这是对创建素数列表的模块的调用。它很好用。
dom=2,8!当我尝试在G95中编译时,这个循环不会递增。M=每个循环2。
拱腹=拱腹+NRP(M)
结束
打印*,'ANS:',至今
阅读*,索法尔
结束程序PEU72
函数NRP(NUM)结果(PHI)
使用素数
隐式无
整数::NUM,PHI,I!,DIF
整数::VAR
I=1
φ=NUM-1
VAR=NUM
做
如果(MOD(NUM,ALLPRIMES(I))==0),那么
φ=φ-((NUM-1)/所有素数(I))
NUM=NUM/ALLPRIMES(I)!这是西尔弗罗斯特不喜欢的台词。没有它,代码绝对可以正常工作,只是时间太长了。
如果结束
I=I+1
VAR=NUM-ALLPRIMES(I)
如果(VAR在直线上

NUM=NUM/ALLPRIMES(I)
您正在更改
NUM
,它将
NRP
作为参数输入。调用
NRP
将其设置为
M
,因此实际上您正在更改
M

Fortran默认情况下通过引用传递参数。(通过@francescalus注释的空中碰撞:“有人试图修改循环内的循环变量m(作为与num关联的实际参数)。这是不允许的。”)

因此,您必须更改for循环或在例程中重新定义
NUM
,所有这些都取决于问题。

在该行中

NUM=NUM/ALLPRIMES(I)
您正在更改
NUM
,它将
NRP
作为参数输入。调用
NRP
将其设置为
M
,因此实际上您正在更改
M

Fortran默认情况下通过引用传递参数。(通过@francescalus注释的空中碰撞:“有人试图修改循环内的循环变量m(作为与num关联的实际参数)。这是不允许的。”)


因此,您必须根据问题更改for循环或在例程中重新定义
NUM

对于操作循环计数器很方便的情况,我建议您使用另一种方法(逻辑相同但符合标准):

M = 2
DO WHILE(M <= 8)
  SOFAR = SOFAR + NRP(M)
  M = M + 1 ! if you need to increment the index
END DO
M=2

DO WHILE(M我建议您使用另一种方法(相同的逻辑,但符合标准),以便于操作循环计数器:

M = 2
DO WHILE(M <= 8)
  SOFAR = SOFAR + NRP(M)
  M = M + 1 ! if you need to increment the index
END DO
M=2

尽管这样做(我不确定它在效率方面是否方便(考虑到矢量化和编译器优化),但这闻起来像是对meI的递归。我真的不明白这一点。你也可以发布Silverfrost和g95上的函数吗?请发布许多运行的非法程序,并给出正确答案。大多数情况下……然后一旦它们突然不运行。这是无效的Fortran,正是Silverfrost编译器抱怨的原因关于:使用语句
NUM=NUM/ALLPRIMES(I)
试图在循环内修改循环变量
m
(作为与
NUM
相关联的实际参数)。这是不允许的。我不确定从效率角度看是否方便(考虑到向量化和编译器优化),但这闻起来像是对meI的递归。我真的不明白这一点。你也可以发布Silverfrost和g95上的函数吗?请发布许多运行的非法程序,并给出正确答案。大多数情况下……然后一旦它们突然不运行。这是无效的Fortran,正是Silverfrost编译器抱怨的原因关于:使用语句
NUM=NUM/ALLPRIMES(I)
试图修改循环内的循环变量
m
(作为与
NUM
关联的实际参数)。这是不允许的。