2014-03-28 4 views
1

추가 처리를 위해 사용자 배열의 주소를 저장하는 절차를 작성하려고합니다. 문제는이 테스트 프로그램에 캡슐화되어 있습니다.다른 유형을위한 하나의 포인터 Fortran

program test_ptr 
    real(4), target, allocatable :: i4(:,:) 
    real(8), target, allocatable :: i8(:,:) 
    real(4), pointer :: p(:,:) 

    allocate(i4(2,2)) 
    allocate(i8(2,2)) 

    p => i4 ! ok 
    p => i8 ! compile error 
end 

컴파일러는 다른 유형의 다른 포인터를 제안합니다. 그러나 real (4) 및 real (8)에 대한 별도의 포인터를 만들고 싶지 않습니다. 나는 일반적이고 압축 된 솔루션을 만들고 다른 유형의 데이터를위한 하나의 포인터를 갖기 위해 노력하고 있습니다. 가능한가?

답변

2

주소를 실제로 저장하려면 다형성에주의해야합니다. 다형 변수에 대한 포인터는 종종 실제 데이터와 다른 주소를 갖는 디스크립터를 가리킨다. 주소를 얻으려면 iso_c_binding 모듈에 정의 된 type(c_ptr)과 함수 c_loc()을 사용하는 것이 좋습니다. C와 인터페이스 할 때만 사용할 필요는 없으며, 순수한 Fortran에서 편리하게 사용할 수있는 몇 가지 장소가 있습니다.

+0

고맙습니다.하지만 어떻게 작동하는지 이해할 수 없습니다. 'p = c_ptr (r4)'이면, 어떻게하면 그 아래에 데이터를 얻을 수 있습니까 (C의'* p'와 같은)? – vovo

+1

그런 다음 포트란'포인터 '가 데이터를 가리 키도록 설정하는'c_f_pointer()'서브 루틴을 사용합니다. 'c_ptr'에 저장되지 않기 때문에 타입을 알아야합니다. –

5

p에 대한 (무제한) 다형성을 사용하여이를 수행 할 수 있습니다.

program test_ptr 
    implicit none 

    real(kind(0.)), target :: r4(2,2) 
    real(kind(0d0)), target :: r8(2,2) 

    class(*), pointer :: p(:,:) 

    ! some assignments, etc. 

    if (...some crazy condition...) then 
    p => r4 
    else 
    p => r8 
    end if 

    select type (p) 
    type is (real(kind(0.))) 
     print *, p 
    type is (real(kind(0d0))) 
     print *, p 
    end select 

end program 

나중에 p를 사용할 때의 select type에 특히주의를 기울이십시오.

+0

_address_ (중요한) 부분이 _pointer_보다 더 중요한 경우 Vladimir F의 [answer] (http://stackoverflow.com/a/22723837/3157076)를 참조하십시오. – francescalus

+0

고마워, 이건 좋은 생각인데, 제 컴파일러는 '(1) 아직 지원되지 않는 무제한의 다형성'이라고 말했다. – vovo

+0

@vovo gfortran 오류 메시지처럼 들립니다. 4.8.2 (아마도 더 일찍, 그러나 나는 체크하지 않았다)이 구조를 지원한다. – francescalus

관련 문제