2017-04-30 4 views
0

안녕하세요. 아래에 나와있는 오류 메시지 중 하나를 강조하기 위해 최소한의 완전하고 검증 가능한 예제 코드를 만들려고했습니다. "(1)에서 인수 'func0'에 유형 불일치가 발생하여 REAL (4)에서 COMPLEX (4)로 전달됨오류가 발생했습니다.

(1)의 오류 메시지가 표시된 코드에 표시됩니다. 또 다른 서브 루틴 내에서 서브 루틴을 호출하려고합니다. 제가 원래 Sub2라는으로 암시 아무것도 추가하지하려고

그러나 그때 func0, FUNC1 암시 적 유형이없는 없다는 오류 메시지가 표시됩니다.

내가 논리를 따라 시도 이 게시물의 내용 : How to call and use a subroutine inside another subroutine in fortran?

Module Sample 

integer :: n,m 

contains 

subroutine Sub1(func0,func1) 

implicit none 

    complex, dimension(-10:10, -10:10), intent(inout) :: func0,func1 
    complex, dimension(-10:10, -10:10) :: Deriv0,Deriv1 


    do while (100 > 0.000001) 

     Deriv0 = Deriv(func0) 
     Deriv1 = Deriv(func1) 

    end do 

end subroutine Sub1 

subroutine Sub2(func3) 
!implicit none : if this line is not commented out, I still get error messages saying func0,func1 do not have implicit types 

    real,dimension(0:20), intent(inout) :: Func3 

    call Sub1(func0,func1) !error message from here, this is line (1) 

end subroutine Sub2 

function Deriv(func) 
implicit none 

complex, dimension(-10:10, -10:10) :: func, Deriv 

    do n=-9,9 
    do m=-9,9 

    Deriv(n,m) = func(n+1,m)-2*func(n,m) 

    end do 
    end do 

end function Deriv 

End Module Sample 

어떻게이 오류를 해결할 수 있습니까? 감사.

답변

2

우리는 다음과 같은 여러 가지 개념을 고려합니다. 범위 지정; 협회; 상속.

질문의 코드에는 모듈 sample과 두 개의 서브 루틴과 하나의 함수 인 네 개의 유효 범위 단위가 있습니다. 이들은 모두 별개이지만 일부 정보는 그들 사이에서 공유됩니다.

첫 번째는 implicit입니다. 모듈에는 implicit이 없으므로 모듈의 범위 지정 단위에 기본 입력 규칙이 적용됩니다. 모듈의 변수와 함수는 모두 명시 적으로 선언됩니다. sub1deriv에는 각각 implicit none이 있으므로 입력 규칙 (암시 적 타이핑 없음)이 명확하게 명시되어 있습니다.

implicit nonesub2으로 지정하면 명시적인 형식 선언에 대한 컴파일러의 불만 사항은 func0func1입니다. implicit none없이 범위 지정 단위 sub2은 호스트 (모듈)의 입력 규칙을 상속하므로 func0func1이 실제입니다.

범위 지정 단위 및 입력 규칙은 another question and its answers에 있습니다. 요약하면 implicit none을 모듈에 넣으십시오.

func0func1을 입력하면 범위 지정의 다른 측면이 생깁니다. sub1sub2은 완전히 다른 범위 지정 단위입니다. 이 두 가지 서브 루틴이 선언에 대한 지식을 공유 할 수있는 유일한 방법은 하나의 형식을 연결하는 것입니다.

여기에는 호스트 연결과 인수 연결의 두 가지 형태가 있습니다.

호스트 연관은 각 서브 루틴이 nm 변수에 액세스 할 수 있다는 것입니다. 변수를 참조하지 않으므로 무시하십시오. 호스트 연결은 sub2에 명시적인 인터페이스 sub1을 제공하므로 컴파일러는 형식 불일치에 대해 불평 할 수 있습니다.

범위 지정 단위가 sub2 인 경우 명시 적 선언은 func0func1입니다. 이것은 implicit none의 오류입니다. 기본 암시 적 타이핑 규칙을 사용하면 실제 스칼라 결과이거나 실제 스칼라 결과 인 함수입니다. 그것들을 복잡한 배열로 원한다면 그것들을 선언 할 필요가 있습니다.

다음과 같은 방식으로 인수 연결이 이루어집니다. 우리는 가짜 인수 sub1을 실제 인수 sub2과 연관시킵니다. 여기서 중요한 것은 어소시에이션입니다. 두 개의 별개의 것들이 동일한 객체를 참조합니다. 두 절차는 각각 명시 적으로 언급되지 않은 것을 공유하지 않습니다. 그러한 가짜 인수와 관련된 실제 인수를 가질 수 있으려면 sub2의 범위에 적절한 것이 있어야합니다. 현재는 아무것도 아닙니다. 한마디로


: 당신은 sub2func0func1의 적절한 선언이 필요합니다. 프로그램을 어떻게 처리 할 것인지에 따라 지역 변수 나 가짜 인수가 될 수 있습니다.

+0

이것은 나를 위해 매우 도움이됩니다. 나는 당신이 제안한 것처럼 sub2에서 func0, func1을 선언함으로써 오류를 수정할 수 있었다. 또한 암시적인 none을 모듈에 추가했습니다. 다른 모든 설명에도 많은 감사를드립니다. 내가 궁금한 점이 있으면 알려 드리 겠지만 지금은 그렇지 않다. 아주 분명하다. 감사! –

0

(면책 조항 :.. 사실 포트란을 모르는이 대답은 WAG입니다)

당신의 Sub2 서브 루틴에서

,도 func0func1 선언, 그들은 매개 변수 아니에요. 코드의 다른 부분과 다른 Sub2에는 implicit none 지시문이 포함되어 있지 않으므로 컴파일러에서는 func0REAL 변수로 가정하므로 형식 오류가 발생합니다 (Sub1COMPLEX 변수가 필요하기 때문에).

내가 어떻게 코드가 어디 Sub2를 호출하지 않기 때문에이 문제를 해결하는 방법을 말할 수 있지만, 아마도 당신은 Sub1에 전달할 곳에서 두 COMPLEX 변수를 얻을 수 있습니다.

+0

나중에 implicit none이 없다는 것을 알았습니다. func0에 대한 다른 오류 메시지가 추가되었습니다. 암시 적 유형이없는 func1입니다. 그래서 나는 먼저이 오류 메시지로 시작한다고 생각했습니다. Func0, Func1이 정의되어서는 안됩니다. 내 Sub2에서 정확히 func0, func1이 정의 된 Sub1을 호출하는 이유입니다. 'contains'부분이 내 모듈의 모든 서브 루틴과 함수를 호출한다고 생각합니다. 각 함수/서브 루틴을 명시 적으로 '호출'하지 않습니다. sub2는 sub1이 필요하기 때문에 여기에서이 호출을 사용했습니다. 답변 해 주셔서 감사합니다. 하지만 난 그것을 고칠 방법을 모르겠다 –

+0

예 : 내 코드는 sub1이나 함수 Deriv를 호출하지 않는다. 그러나 나는 거기에서 오류를 얻지 않는다. 내 모듈은 이것을 처리하는 'contains'를 가지고 있습니다 (나는 생각하니?) 일단이 서브 루틴 Sub2를 추가하면 Sub1을 호출하려고 할 때 오류가 발생합니다. 분명히이 논리에 문제가있어 Sub2를 어떻게 호출 할 것을 제안합니까? Sub1 또는 Function Deriv를 호출하지 않으므로 Sub2를 호출해야하는 이유는 무엇입니까? –

+0

@Integrals'Sub2'를 호출 할 필요가 없습니다. 그것은 당신이 그것을 어떻게 의도했는지에 대한 단서를 제공했을 것입니다. 지금 당장이 코드가 무엇을 달성해야하는지 알지 못합니다. 그래서 대신 무엇을해야 할지를 말할 수 없습니다. – melpomene