如何保持递归Fortran子例程中定义的变量不会在内部调用时更新?

时间:2013-04-28 03:17:26

标签: recursion fortran scope subroutine

使用以下代码,当变量aa1等于2时,我希望递归子例程创建2个长度为4的嵌套do循环(maxdev = 4)。

我试图通过变量count(子例程中的count1)来控制嵌套级别。但是,当子例程自己调用时,count1的值不会在第一次调用中保留。我希望外部循环保留count1为1的值,第二个循环的值为count1为2,以反映嵌套级别。

我不确定如何指定程序以实现这一目标。相反,当创建内部循环的调用返回到外部循环时,外部循环中的count1的值已经更改,并反映了它在内部循环中的增量。

program fragarrays
implicit none

integer::gridres,maxdev,a,count
integer, allocatable:: x(:)

open(unit=1,file='D:/output11.txt',status='unknown')

gridres=2

maxdev=gridres*gridres

do a = 1,2 
    count=0    
    allocate(x(a))
    call assigncell(a,maxdev,count,x)
    deallocate(x)
end do

contains

recursive subroutine assigncell(a1,maxdev1,count1,x1)
    integer:: a1,maxdev1,b
    integer::count1
    integer,dimension(a1):: x1

    count1=count1+1
    do b=1,maxdev1
        x1(count1)=b
        write (1,*)count1,x1(count1),b,a1
        if(count1.lt.a1)then
            call assigncell (a1,maxdev1,count1,x1)
        end if

    end do

end subroutine assigncell

end program fragarrays

2 个答案:

答案 0 :(得分:3)

使count1成为局部变量而不是参数。它的变化是因为它隐含了一个inout参数,并且该调用应该改变它。作为局部变量,它对子例程的每次调用都是唯一的。例如:

module MyMod
contains
recursive subroutine assigncell(a1,maxdev1,count1_arg,x1)
    integer, intent (in):: a1,maxdev1
    integer, intent (in)::count1_arg
    integer,dimension(a1):: x1
    integer :: count1, b

    count1 = count1_arg
    write (*, *) "entering subr. with", a1, count1
    count1=count1+1
    write (*, *) "changed to: a1, count1=", a1, count1
    do b=1,maxdev1
        x1(count1)=b
        write (1,*)count1,x1(count1),b,a1
        if(count1.lt.a1)then
            call assigncell (a1,maxdev1,count1,x1)
        end if

    end do
    write (*, *) "still at: a1, count1:", a1, count1

end subroutine assigncell

end module MyMod

program fragarrays
use MyMod
implicit none

integer::gridres,maxdev,a,count
integer, allocatable:: x(:)

open(unit=1,file='output11.txt',status='replace')

gridres=2

maxdev=gridres*gridres

do a = 1,2
    count=0
    allocate(x(a))
    write (*, *) "calling with", a, count
    call assigncell(a,maxdev,count,x)
    deallocate(x)
end do


end program fragarrays

P.S。将count1参数设置为子例程的局部替代方法:为该参数赋予VALUE属性:

...
recursive subroutine assigncell(a1,maxdev1,count1,x1)
    integer, intent (in):: a1,maxdev1
    integer, VALUE ::count1
    integer,dimension(a1):: x1
    integer :: b

    write (*, *) "entering subr. with", a1, count1
...

答案 1 :(得分:-1)

我认为(我还没有完成Fortran 27年)Fortran通过引用传递参数,而不是按值传递参数。

你需要的是每次递归调用都要拥有它自己的一组变量,并在你重复进入和退出时退出。

GNU Fortran Doc个州

8.11.1%VAL()构造

  

%VAL(ARG)

     

%VAL()构造指定参数arg将按值传递,而不是通过引用或描述符传递。

我注意到这是真的用于外部定义的函数,以满足那些用默认情况下通过值传递的语言编写的函数。但我认为你需要做的就是你的功能。

CALL assigncell (%VAL(first_var), %VAL(second_var), ... %VAL(last_var))       

同样,我不是没有Fortran超过F77,所以我的研究和思考可能不合时宜。