2016-10-01 2 views
2

간결한 제목으로 어려움을 겪고 있지만 복잡하지는 않습니다. 구조 (파생 된 형식) 반환하는 함수가 및 복사/다른 구조를 가리 키지 않고 함수를 호출하는 동안 구조체의 일부만 참조하는 간단한 방법을 찾고 있어요.구조체/파생 형식을 반환하는 함수 참조

program main 

    real :: xx = 1. 
    real :: yy = 2. 

    ! works fine but what I want is to be 
    ! able to return %tx and %ts separately 

    print *, " tax ", tax(xx,yy) 

    ! just guessing at possible syntax here, but neither works 

    print *, " tax ", tax%tx(xx,yy) 
    print *, " tax ", tax(xx,yy)%tx 

contains 

function tax(x,y) 

    real :: x, y 

    type tTax 
     real :: tx, ty 
    end type tTax 

    type(tTax) :: tax 

    tax%tx = x * 100. 
    tax%ty = y * 100. 

end function tax 

end program main 

f90/f95 기능 세트로 제한되지만 f2003 답변도 포함시켜 주시기 바랍니다.

그리고 나는 그것이 존재한다면 여기에 간단한 것을 정말로 찾고 있습니다. 그렇지 않으면, 서브 루틴으로 대체하는 것이 더 나을 것입니다 (대안으로 함수를 포인터로 유지하면서 포인터, 인터페이스 등을 추가하는 경우).

구조체 대신 2 차원 배열을 반환하고 동일한 기본 문제가 발생했습니다. 작동하지만 모든 배열 섹션을 인쇄 할 수는 없습니다.

심지어는 ()이 색인 및 색인을 위해 []을 사용하는 python과 같은 언어와 달리 Fortran의 함수와 배열 섹션에 모두 사용되므로이 구문에서 추측하기가 어려웠습니다. 따라서 함수와 색인을 섞어도되는 것은 당연합니다. tax(xx,yy)[1,:]).

답변

3

함수 return을 사용하여 파생 데이터 형식의 이름을 오버로드하여 사용자 정의 생성자를 만들 수 있습니다.

자유롭게 Fortran 2003 표준의 associate 구조를 사용하면 메모리 누출이 자주 발생하는 포인터를 복사하거나 사용하지 않고 특정 유형의 구성 요소에 액세스 할 수 있습니다.

Fortran 2003으로 제한하는 특별한 이유가 있습니까? 대부분의 인기있는 컴파일러는 Fortran 2008의 상당 부분을 지원합니다.

다음 코드

module mymod 

    ! Explicit typing only 
    implicit none 

    ! Declare derived data type 
    type tTax 
    real :: tx, ty 
    end type tTax 

    ! User-defined constructor 
    interface tTax 
    module procedure tax 
    end interface tTax 

contains 

    function tax(x, y) result (return_value) 
    real, intent (in) :: x, y 
    type (tTax)  :: return_value 

    return_value%tx = x * 100.0 
    return_value%ty = y * 100.0 

    end function tax 

end module mymod 

program main 

    use mymod 

    ! Explicit typing only 
    implicit none 

    real  :: xx = 1.0, yy = 2.0 
    type(tTax) :: foo 

    print *, " tax ", tax(xx,yy) 
    print *, " tax ", tTax(xx, yy) 

    ! Invoke the user-defined constructor 
    foo = tTax(xx, yy) 

    ! Fortran 2003's associate construct 
    associate(& 
     tx => foo%tx, & 
     ty => foo%ty & 
     ) 
     print *, " tax ", tx, ty 
    end associate 

end program main 

은 당신이 표현 여부의 구성 요소 또는 요소를 참조 할 수 있습니다 단지 여부,

gfortran -Wall -o main.exe mymod.f90 main.f90 
./main.exe 
    tax 100.000000  200.000000  
    tax 100.000000  200.000000  
    tax 100.000000  200.000000 
+1

감사합니다. +1. 이 질문에서 짐작했던 것처럼 fortran은이 추가 작업을 수행하여 실용적인 관점에서 볼 때 조금 더 단순한 서브 루틴을 사용할 수 있습니다. 현재는 테스트 할 새 컴파일러가 충분하지 않습니다. 어쨌든. ;-)하지만 이것은 멋지다, 고마워! – JohnE

+0

f2003 없이는 main에서'associate()'를 사용할 수 없다는 것을 알고 있습니다.하지만 모듈 자체만으로 컴파일해야합니까? 내 f90 컴파일러는 tTax 이름을 사용하여 유형 및 인터페이스에 대해 불평하지만 별도로 컴파일합니다 (물론 주 인터페이스는 해당 경우 작동하지 않습니다). tx가 아니라 main에서 foo % tx를 사용할 수 있다면 내 perspecive에서 충분한 해결책이 될 것입니다. – JohnE

+0

@VladimirF 또는 jlok : 여기 내 의견에 대한 쉬운 대답이 있습니까? 또는 별도의 질문으로 질문 할 가치가 있습니까? – JohnE

3

문제는 괄호 기호에 있지를 얻을 수 있습니다.

포트란에서는 허용되지 않습니다. 변수 또는 상수 이름이나 연관 이름에 대해서만 % 구문 또는 배열 indexing()을 사용할 수 있습니다.

+0

맞아요, 그건 제 일의 가설이었습니다.하지만 저는 항상 포트란의 정신에 반하는 것처럼 보이는 파이썬 식의 세련된 설탕 알토를 기대하고 있습니다. ;-) – JohnE

+0

@JohnE 다음은 Python Fortran Rosetta Stone http : // www.fortran90.org/src/rosetta.html – jlokimlin

+0

@jlokimlin 그래, 흥미롭게도 내 문제에 대해 흥미로운 점은 fortran ** 서브 루틴 **을 파이썬/numpy와 동일하게 취급한다는 것입니다! 여기 내 문제는 분명히 내가 파이썬 함수처럼 포트란 함수를 작동 시키려고 노력하고 있고, 파이썬처럼 포트란을 좀 더 열심히 만들려 고 노력 중이다. – JohnE

관련 문제