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

How to alter a fortran program index variable in a while loop?

我有以下代码:

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

出于优化目的,我想在每次迭代时除以 num,这是 while 循环的一个条件。当我这样做时,我的 (silverfrost) 编译器抛出一个错误(Active DO loop altered),而 G95 编译器 完全中断,根本不迭代第一个循环。我试过使用 DO - IF - EXIT 术语,none 有效。如何实现每次除Num,Allprimes(i)递增的情况?

行中

NUM = NUM/ALLPRIMES(I) 您正在更改 NUM,其中输入 NRP 作为参数。 NRP 的调用给出了 M 所以实际上你正在改变 M.

Fortran 默认通过引用传递参数。 (以及@francescalus 评论的空中碰撞:"there is an attempt to modify the loop variable m (as the actual argument associated with num) inside the loop. This is not allowed.")。

所以你必须根据问题改变你的 for 循环或在你的例程中重新定义 NUM

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

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

编辑:

How to alter a fortran program index variable in a while loop?

再看题名,我觉得这不是替代,而是字面上的回答。