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

时间:2018-09-08 23:34:35

标签: 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 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循环条件)除以。执行此操作时,我的(白霜)编译器将引发错误(Active DO循环已更改),而G95编译器 完全中断,完全不迭代第一个循环。我尝试使用DO-IF-EXIT术语,但都没有用。如何实现每次Num被除法并且Allprimes(i)递增的情况?

2 个答案:

答案 0 :(得分:3)

在行

NUM = NUM/ALLPRIMES(I) 您正在更改NUM作为参数输入的NRPNRP的调用将其命名为M,因此实际上您正在更改M

Fortran默认情况下通过引用传递参数。 (以及@francescalus的空中碰撞评论:“试图在循环内部修改循环变量m(与num相关的实际参数)。这是不允许的。”)。

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

答案 1 :(得分:1)

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

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

编辑:

  

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

再次阅读问题的标题,我认为这不是替代,而是字面上的答案。