프로시저의 인자가 포인터이면 explicit interface를 갖아야 한다.

explicit interface란

- 외부 프로시저의 경우 프로시저를 사용하는 프로그램에서 interface block을 둔다.

- 프로시저를 모듈에 둔다.

정방행렬에서 대각원소를 뽑는 프로그램

PROGRAM test_diagonal

IMPLICIT NONE

! 서브루틴의 dummy argument로 pointer를 쓴다면 꼭 explicit interface를 가져야 한다.
INTERFACE
SUBROUTINE get_diagonal(ptr_a, ptr_b, error)
INTEGER, DIMENSION(:,:), POINTER :: ptr_a
INTEGER, DIMENSION(:), POINTER :: ptr_b
INTEGER, INTENT(OUT) :: error
END SUBROUTINE get_diagonal
END INTERFACE

INTEGER :: i, j, k
INTEGER :: istat
INTEGER, DIMENSION(:,:), POINTER :: ptr_a
INTEGER, DIMENSION(:), POINTER :: ptr_b
INTEGER :: error

! error 1 happen
CALL get_diagonal(ptr_a, ptr_b, error)
WRITE (*,*) 'No pointers allocated: '
WRITE (*,*) ' Error = ', error

! error 2
ALLOCATE (ptr_a(10,10), STAT = istat)
ALLOCATE (ptr_b(10), STAT = istat)
CALL get_diagonal(ptr_a, ptr_b, error)
WRITE (*,*) 'Both pointers allocated: '
WRITE (*,*) ' Error = ', error

! error 3
DEALLOCATE (ptr_a, STAT = istat)
DEALLOCATE (ptr_b, STAT = istat)
ALLOCATE (ptr_a(-5:5, 10), STAT = istat)
CALL get_diagonal(ptr_a, ptr_b, error)
WRITE (*,*) 'Array on ptr_a not square '
WRITE (*,*) ' Error = ', error

DEALLOCATE (ptr_a, STAT = istat)
ALLOCATE (ptr_a(-2:2, 0:4), STAT = istat)
k = 0
DO j = 0, 4
DO i = -2, 2
k = k + 1
ptr_a(i, j) = k
END DO
END DO

CALL get_diagonal(ptr_a, ptr_b, error)
WRITE (*,*) 'ptr_a allocated & square; ptr_b not allocated: '
WRITE (*,*) ' Error = ', error
WRITE (*,*) 'Square Matrix '
WRITE (*,100) ((ptr_a(i, j), i = -2, 2), j = 0 ,4)
100 FORMAT (1X, 5I5)
WRITE (*,*) 'Diagonal '
WRITE (*,100) ptr_b



END PROGRAM test_diagonal

SUBROUTINE get_diagonal(ptr_a, ptr_b, error)

! error code
! 0 - no error
! 1 - ptr_a not associated on input
! 2 - ptr_b already associated on input
! 3 - array on ptr_a not square
! 4 - unable to allocate memory for ptr_b

IMPLICIT NONE

INTEGER, DIMENSION(:,:), POINTER :: ptr_a ! pointer는 INTENT()를 쓸 수 없다.
INTEGER, DIMENSION(:), POINTER :: ptr_b
INTEGER, INTENT(OUT) :: error

INTEGER :: i
INTEGER :: istat
INTEGER, DIMENSION(2) :: l_bound
INTEGER, DIMENSION(2) :: u_bound
INTEGER, DIMENSION(2) :: extent

IF (.NOT. ASSOCIATED(ptr_a)) THEN
error = 1
ELSE IF (ASSOCIATED(ptr_b)) THEN
error = 2
ELSE
l_bound = LBOUND(ptr_a)
u_bound = UBOUNd(ptr_a)
extent = u_bound - l_bound + 1

IF (extent(1) /= extent(2)) THEN
error = 3
ELSE
ALLOCATE(ptr_b(extent(1)), STAT = istat)
IF ( istat /= 0 ) THEN
error = 4
ELSE
DO i = 1, extent(1)
ptr_b(i) = ptr_a(l_bound(1)+i-1,l_bound(2)+i-1)
END DO
END IF

error = 0

END IF
END IF

END SUBROUTINE get_diagonal

위 소스를 get_diag.f95로 저장

컴파일 및 프로그램 테스트



'Programming > Fortran' 카테고리의 다른 글

sort and search using binary tree  (0) 2009.01.14
Pointer-valued function  (0) 2009.01.14
Insertion sort using linked list  (0) 2009.01.10
usign direct access, formatted file  (0) 2009.01.06
NAMELIST I/O  (0) 2009.01.06

+ Recent posts