2

次のコードでは、変数aa1が 2 の場合、再帰サブルーチンで長さ 4 (maxdev=4) のネストされた 2 つの do ループを作成します。

countネストのレベルを変数(count1サブルーチン内) で制御しようとしています。ただし、サブルーチンが単独で呼び出されると、値count1は最初の呼び出し内で保持されません。入れ子のレベルを反映するために、外側のループcount1が 1 の値を保持し、2 番目のループが 2 の値を保持するようにします。count1

これが達成されるように、プログラムを指定する方法がわからない。代わりに、内側のループを作成する呼び出しが外側のループに戻ると、外側のループの値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
4

2 に答える 2

4

引数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

PS 引数をサブルーチンに対してローカルにする別の方法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
...
于 2013-04-28T03:44:28.110 に答える
-1

Fortran はパラメーターを値ではなく参照で渡すと思います (私は Fortran を 27 年間使用していません)。

必要なのは、再帰呼び出しごとに独自の変数セットを持ち、再帰および逆戻りするときに元に戻すことです。

このGNU Fortran Docの状態

8.11.1 %VAL() コンストラクト

%VAL(引数)

%VAL() コンストラクトは、引数 arg が参照または記述子ではなく、値によって渡されることを指定します。

これは実際には外部で定義された関数用であり、デフォルトで値を渡す言語で記述された関数に対応するためであることに注意してください。しかし、あなたの機能はこれを行う必要があると思います。

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

繰り返しになりますが、私は F77 以降の Fortran を使用していないため、私の研究と思考は的外れである可能性があります。

于 2013-04-28T03:29:00.003 に答える