할당 된 배열을 서브 루틴에서 포트란의 메인 프로그램으로 전달합니다. 사용 또는 모듈? 상호 작용?

Aug 16 2020

서브 루틴에 배열을 할당하고 메인 프로그램에서이 배열을 사용하여 다른 서브 루틴에 전달하고 싶습니다. 과거 (F77?)는 공통 블록에서 통과 할 수 있었지만 현재는 모듈을 사용하는 것이 선호되는 절차 인 것 같습니다. 코드 예제에서와 같이 이것을 시도하면 컴파일러가

Rank mismatch in argument ‘f’ at (1) (scalar and rank-1)

분명히 메인 프로그램은 'f'가 스칼라라고 생각합니다.하지만이 코드는 서브 루틴 내부와 메인 프로그램 모두에서 1 차원 배열로 선언했음을 의미합니다. 내가 무엇을 놓치고 있습니까?

모듈의 일부로 변수를 선언하는 것과 같은 변형을 시도해 보았지만 컴파일을 오류없이 만들 수 있다고 생각할 수있는 것은 없었습니다 (일부는 더 많은 오류를 생성했습니다 ;-(). 모든 통찰력이 가장 감사합니다.

          module subs
        contains
        subroutine makef(f)
        end subroutine makef
      end module subs
c-----------------------------------------------------------------------
      program work

      use subs
      implicit none
        real, allocatable :: f(:)

      call makef(f)

      write (*,*) f
      stop
      end
c---------------------------------------------------------------------
      subroutine makef(f)
      implicit none

      real, allocatable, intent(out) :: f(:)
      integer :: i
      integer :: is

      is=10
      allocate(f(-is:is))

      do i=-is,is
        f(i)=i
      end do
      return
      end subroutine makef

답변

2 francescalus Aug 16 2020 at 17:19

Fortran의 모듈은 다른 언어에서 정의 된 것에 대한 정보 만 제공하는 헤더 파일과 다릅니다. "지연된 정의"(서브 모듈) 개념이 있지만이 경우 모듈은 단순히 존재를 가리 키려고 시도하는 것이 아니라 서브 루틴에 대한 모든 것을 말해야합니다.

질문의 예에서 우리는 : 메인 프로그램; subs모듈 프로 시저가 있는 모듈 makef; 외부 서브 루틴 makef.

주 프로그램은 모듈 subs과 그 절차 makef를 사용하므로 주 프로그램에서 참조 makef하는 것은 외부 서브 루틴이 아닌 해당 모듈 절차를 참조하는 것 makef입니다.

모듈 서브 루틴 makef에는 f선언문이없는 인수 가 있으므로 암시 적으로 선언 된 스칼라 / 외부 함수가됩니다. 이것이 컴파일러의 메시지입니다. implicit none메인 프로그램과 외부 서브 루틴 에서처럼 모듈에서 사용 하십시오.

서브 루틴의 전체 정의는 모듈에 배치되어야합니다.

module subs
  implicit none
contains
  subroutine makef(f)
    real, allocatable, intent(out) :: f(:)
    integer :: i
    integer :: is

    is=10
    allocate(f(-is:is))

    do i=-is,is
      f(i)=i
    end do
  end subroutine makef
end module subs

또는 외부 프로 시저의 이후 구현을 참조하려는 경우 인터페이스 블록이 서브 루틴 자체를 선언하지 않고 모듈에 기능 할 수 있습니다. 이 경우에도 완전한 인터페이스를 지정해야합니다.

module subs
  implicit none

! An interface block to give an explicit interface to the external subroutine makef
  interface
     subroutine makef(f)
       implicit none
       real, allocatable, intent(out) :: f(:)
     end subroutine makef
  end interface
end module subs

이 경우 인터페이스 블록을 선호하지 마십시오.

VladimirF Aug 16 2020 at 13:07

첫 번째와 마지막 줄의 복사본 만 모듈에 배치했습니다. 작동하지 않습니다. 전체 서브 루틴을 모듈로 이동해야합니다.