할당 된 배열을 서브 루틴에서 포트란의 메인 프로그램으로 전달합니다. 사용 또는 모듈? 상호 작용?
서브 루틴에 배열을 할당하고 메인 프로그램에서이 배열을 사용하여 다른 서브 루틴에 전달하고 싶습니다. 과거 (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
답변
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
이 경우 인터페이스 블록을 선호하지 마십시오.
첫 번째와 마지막 줄의 복사본 만 모듈에 배치했습니다. 작동하지 않습니다. 전체 서브 루틴을 모듈로 이동해야합니다.