首页 > 解决方案 > 如何在while循环中更改fortran程序索引变量?

问题描述

我有以下代码:

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 changed),并且 G95 编译器完全中断,根本没有迭代第一个循环。我试过使用 DO - IF - EXIT 术语,但都不起作用。如何实现 Num 每次都被划分,并且 Allprimes(i) 递增的情况?

标签: fortranfortran95

解决方案


在行

NUM = NUM/ALLPRIMES(I) 您正在更改作为参数NUM输入的内容。实际上你正在改变它NRP的调用。NRPMM

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

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


推荐阅读