2014-08-30 2 views
2

다음 코드를 작성하는 올바른 방법은 무엇입니까? 내가 REAL(KIND=8), DIMENSION(0:10)으로 barptr를 선언하는 경우fortran에 포인터 인수가 전달됨

PROGRAM foo 

    INTEGER :: x 
    REAL(KIND=8), TARGET, DIMENSION(0: 10) :: array 
    REAL(KIND=8), POINTER, DIMENSION(:) :: ptr 

    ptr => array 

    CALL bar(ptr) 

END PROGRAM foo 

SUBROUTINE bar (ptr) 

    REAL(KIND=8), POINTER, DIMENSION(:) :: ptr                                                     
    INTEGER x 
    DO x =0, 10 
    ptr(x) = 2 // seg faults 
    ENDDO 

END SUBROUTINE bar 

그것은 작동합니다. 하지만 일반적으로 전달 된 배열의 크기를 알지 못할 수도 있으므로 ptr을 일부 배열에 대한 포인터로 선언하는 방법이 있습니까? 나는 이것을 컴파일 중이다 gfortran

+1

이는 경우가 어디 _explicit interface_는'foo'의'bar'에 필요합니다. 예를 들어 http://stackoverflow.com/q/9374691/3157076을 참조하십시오. – francescalus

+0

C를 복제하려고하는 것 같습니다. Fortran에서 생각하는 것이 좋습니다. Bálint의 대답을주의 깊게 읽으십시오. Ian도 옳습니다. –

답변

2

프로 시저에 더미 인수가 있으면 포인터로 명시적인 인터페이스가 호출 범위에 필요하다.

은 (는 명시 적 인터페이스를 필요로 여러 가지가 있으며, 포인터 더미는하지만 하나입니다.) 당신은 메인 프로그램 안에 당신의 서브 루틴을위한 인터페이스 블록을 넣어 것을 명시 적 인터페이스를 직접 제공 할 수

. 대안과 멀리, 멀리, 더 나은 옵션은 서브 루틴을 모듈 안에 넣고 그 모듈을 메인 프로그램에서 사용하는 것입니다. 세 번째 대안은 서브 루틴을 호출 범위의 내부 프로 시저로 만드는 것입니다.

Fortran 2003에서 포인터를 다른 점을 가리 키도록하려는 경우에만 포인터를 사용해야합니다. 실제로 포인터가 값처럼 작동하는 경우 포인터를 대신 사용한다면 allocatables를 대신 사용해야합니다.

2

"적절한"방법으로 무엇을 의미 하느냐에 달려 있습니다. IanH 이미 pointed out으로, 가능한 경우 모듈 대신 패키지를 통해 명시 적 인터페이스가 필요하고 포인터 대신 allocatables를 사용해야합니다.

서브 루틴 내에서 배열의 할당 상태를 변경하지 않고 해당 요소를 조작하려는 경우 서브 루틴 내에서 단순한 가정 된 모양 배열을 사용한다는 점을 추가합니다. 아래에서 실용적인 예를 찾으십시오. 더 몇 가지 참고 사항 :

  • 는 모든 컴파일러가 실수에 대한 일종의 바이트 수를 사용하지 real(kind=8)를 사용하지 마십시오. 배정도 정확도를 원하면 다음과 같이 명시 적으로 요청하십시오. array(:) = 2.0_dp

그리고 여기 예 :

  • 그냥 상수 값으로 배열을 채우기 위해 원하는 경우, 그것을 간단한 방법으로 할

    module accuracy 
        implicit none 
    
        integer, parameter :: dp = kind(1.0d0) 
    
    end module accuracy 
    
    
    module barmodule 
        use accuracy 
        implicit none 
    
    contains 
    
        subroutine bar(array) 
        real(dp), intent(inout) :: array(:) 
    
        integer :: ii 
    
        do ii = 1, size(array) 
         array(ii) = ii 
        end do 
    
        end subroutine bar 
    
    end module barmodule 
    
    
    program foo 
        use accuracy 
        use barmodule 
        implicit none 
    
        real(dp), dimension(0:10) :: array 
        call bar(array) 
    
    end program foo 
    
  • +2

    배열의 인덱스가 0이되도록하려면 서브 루틴에서 배열을'array (0 :)'로 선언 할 수 있습니다. 이는 형상을 가정 할 수는 있지만 시작 색인을 지정합니다. 이는 시작 색인을 인수로 전달할 때까지 일반화 할 수 있습니다. –

    +0

    네 말이 맞아! 감사! 이것은 내가 여러 번 앨 레디 히트 한 것입니다 ... 나는 포스트에서 appropraite 부분을 제거했습니다. –

    관련 문제