21

次のコードは、渡そうとしている割り当て可能な配列が正しく認識されていないため、セグメンテーション違反を返しています(サイズは1を返しますが、3である必要があります)。このページ(http://www.eng-tips.com/viewthread.cfm?qid=170599)では、同様の例がF95で正常に機能することを示しているようです。コードファイルの拡張子は.F90ですが、F95に変更してみたところ、gfortranを使用してコンパイルしています。

私の推測では、問題は、割り当て可能な配列をサブルーチンに渡す方法にあるはずです。私は何が間違っているのですか?

!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%!
 PROGRAM test
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%!
 IMPLICIT NONE
 DOUBLE PRECISION,ALLOCATABLE :: Array(:,:)
 INTEGER                      :: iii,jjj

 ALLOCATE(Array(3,3))
 DO iii=1,3
 DO jjj=1,3
    Array(iii,jjj)=iii+jjj
    PRINT*,Array(iii,jjj)
 ENDDO
 ENDDO
 CALL Subtest(Array)

 END PROGRAM
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%!
 SUBROUTINE Subtest(Array)
 DOUBLE PRECISION,ALLOCATABLE,INTENT(IN) :: Array(:,:)
 INTEGER                                 :: iii,jjj

 PRINT*,SIZE(Array,1),SIZE(Array,2)
 DO iii=1,SIZE(Array,1)
 DO jjj=1,SIZE(Array,2)
    PRINT*,Array(iii,jjj)
 ENDDO
 ENDDO

 END SUBROUTINE
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%!
4

3 に答える 3

32

プロシージャに割り当て可能なダミー引数がある場合は、呼び出し元のスコープに明示的なインターフェイスが必要です。

(明示的なインターフェースを必要とするものはたくさんありますが、割り当て可能なダミーは1つだけです。)

メインプログラム内にサブルーチンのインターフェイスブロックを配置することにより、その明示的なインターフェイスを自分で提供できます。代替のはるかに優れたオプションは、サブルーチンをモジュール内に配置し、そのモジュールをメインプログラムで使用することです。明示的なインターフェイスが自動的に作成されます。リンクを提供したeng-tipsサイトにこの例があります-xwbによる投稿を参照してください。

ダミー引数が割り当て可能な属性を持つことは、その割り当てステータスに関連する何かを行う場合にのみ意味があることに注意してください-ステータスのクエリ、再割り当て、割り当て解除など。

于 2012-10-24T23:23:50.337 に答える
8

arrayまた、割り当て可能なダミー引数はで宣言されていることに注意してくださいintent(in)。これは、その割り当てステータスが関連する実際の引数のステータスになることを意味します(プロシージャ中に変更されない場合があります)。サブルーチンに渡される実際の引数は割り当てられていない可能性があるため、明示的なインターフェイスを使用している場合でも、参照するのは違法です。コンパイラはこれを認識せず、sizeそのような場合のような照会の動作は定義されていません。

したがって、その内容を参照する前に、まずarraywithの割り当てステータスを確認する必要があります。さらに、とallocated(array)を使用して配列全体にループを実装することをお勧めします。これは、一般に、の境界について確信が持てないためです。lbounduboundarray

subroutine subtest(array)
  double precision, allocatable, intent(in) :: array(:,:)
  integer                                   :: iii, jjj

  if(allocated(array)) then
    print*, size(array, 1), size(array, 2)
    do iii = lbound(array, 1), ubound(array, 1)
      do jjj = lbound(array, 2), ubound(array, 2)
        print*, array(iii,jjj)
      enddo
    enddo
  endif  
end subroutine
于 2012-10-25T16:09:41.370 に答える
2

これは、モジュールで割り当て可能なダミー引数を使用する簡単な例です。

module arrayMod   
  real,dimension(:,:),allocatable :: theArray    
end module arrayMod

program test
   use arrayMod
   implicit none

   interface
      subroutine arraySub
      end subroutine arraySub
   end interface

   write(*,*) allocated(theArray)
   call arraySub
   write(*,*) allocated(theArray) 
end program test

subroutine arraySub
   use arrayMod

   write(*,*) 'Inside arraySub()'
   allocate(theArray(3,2))
end subroutine arraySub
于 2016-07-11T20:40:38.037 に答える