Fortran은 메인 프로그램, 외부 프로 시저 및 모듈 등 다양한 "프로그램 단위"간에 데이터를 작성, 저장, 사용 및 전달하는 여러 가지 방법을 제공합니다. 아시다시피 각 프로그램 단위에는 호스트 연결을 통해 호스트에 포함 된 변수 나 프로 시저에 액세스 할 수있는 내부 절차가 포함될 수 있습니다. 이것은 종종 장점으로 간주됩니다. 그의 의견에 @HighPerformanceMark 이미 언급 한 바와 같이, 호스트 협회 또는 사용-연결을 사용하는 경우에 대한 일반적인 지침은 다음에 선언 된 루틴 만 (또는 주로) 사용되는 변수가된다
사용 호스트 연결시 동일한 모듈을 사용하고 여러 모듈에서 사용할 변수를 정의하려는 경우 use-association을 사용하십시오.
주 프로그램의 대부분 또는 모든 호스트 변수가 각 내부 프로 시저 (약 12 개 정도의 서브 루틴). 그렇다면 호스트 연관성이 매우 합리적인 옵션처럼 보이고 각 서브 루틴에 명시 적으로 인수를 전달할 필요가 없습니다. 다른 한편, 각 서브 루틴이 실제로 변수의 서브 세트만을 사용한다면, 서브 루틴에 대해 더 명확히하는 것이 합리적 일 수 있습니다.
필자와 마찬가지로 일반적으로 인수 목록에서 선언되지 않은 프로 시저 내에서 변수를 사용하는 것은 불편합니다. 이것은 부분적으로 args 목록이 자체 문서화하는 방식을 좋아하고 코드와 데이터가 조작되는 방식에 대해 추론하는 데 도움이되기 때문입니다. 다른 직원과 공동 작업을하거나 코드에서 약간의 시간을 보내고 내 기억이 희미 해지면 더욱 그렇습니다. 그러나 호스트 연계를 피하는 이유가 거의 없다는 것을 알았습니다. 호스트 연계가 어떻게 작용하고 전략이 있는지 알고있는 한.
실제로 내부 프로 시저와 호스트 연결을 자주 사용하는 경향이 있습니다 (특히 짧은 함수/서브 루틴의 경우). 느슨하게 호스트를 "객체"로, 변수를 "속성"으로, 그리고 모든 내부 절차를 작업을 수행하는 객체의 "메소드"와 매우 비슷하게 생각하면 도움이됩니다. 물론, 이는 단순화하는 것이지만, 실제로 그것은 요점입니다.
더 복잡한 프로그램의 경우 "주"프로그램 자체에서 호스트 연결의 양을 줄입니다.이 주 프로그램은 주로 적절한 순서와 컨텍스트로 다양한 서브 루틴을 호출하기 위해 존재합니다. 이 경우 use-association
을 활용하고이를 필요로하는 프로그램 단위 내에서 직접 (예 : 절차, 변수, 유형, 매개 변수) use
모듈 엔티티를 선택할 수 있습니다. only:
으로 필요한 모듈 엔티티에만 액세스를 추가로 제한 할 수 있습니다. 이렇게하면 가독성이 향상되고 데이터 흐름이 명확하게 표시됩니다. 나중에 코드를 업데이트하는 것이 더 간단합니다. 상속, 캡슐화, 기타 ...하지만 포트란 스타일. 어느 것이 실제로 꽤 좋다.
다음은 저와 Fortran에서 작업 한 중간 규모 프로젝트에서 작동하는 예제 프로그램 구조입니다. 필자는 널리 사용되는 (정적) 매개 변수를 별도의 모듈 (또는 함수에 따라 그룹화 된 경우 모듈)에 보관하고 싶습니다. 파생 된 유형 및 유형 바인드 프로 시저를 다른 별도 모듈에 보관합니다. 유용 할 경우 특정 모듈 엔티티를 다른 프로그램 단위에서 액세스 할 수 없도록 private
으로 만듭니다. 그리고 나는 그것이라고 생각한다.
module params
implicit none
public !! All items public/accessible by default.
integer, parameter :: dp = kind(0.d0)
integer, parameter :: nrows = 3
real(dp), parameter :: one=1.0_dp, two=2.0_dp
...
end module params
module types
use params, only: dp, nrows
implicit none
public !! Public by default.
private :: dim2
...
integer, parameter :: dim2 = 3
...
type :: A
integer :: id
real(dp), dimension(nrows,dim2) :: data
contains
procedure, pass :: init
end type A
...
contains
subroutine init(self, ...)
...
end subroutine init
...
end module types
module utils
implicit none
private !! Private by default.
public :: workSub1, workSub2, subErr
...
integer,save :: count=0 !! Accessible only to entities in this module.
...
contains
subroutine workSub1(...)
...
end subroutine workSub1
subroutine workSub2(...)
...
end subroutine workSub2
subroutine subErr(...)
...
end subroutine subErr
end module utils
program main
!! An example program structure.
use params, only: dp
implicit none
real(dp) :: xvar, yvar, zvar
integer :: n, i
logical :: rc
call execute_work_subroutines()
contains !! Internal procs inherit all vars declared or USEd.
subroutine execute_work_subroutines()
use types, only: A
type(A) :: DataSet
!! begin
call DataSet%init(i)
do i = 1,n
call workSub1(xvar,yvar,zvar,A,i,rc)
if (rc) call subErr(rc)
call workSub2(A,rc)
if (rc) call subErr(rc)
enddo
end subroutine execute_work_subroutines
end program main
1이 또한 서브 모듈,하지만 난 그들과 함께 익숙하지 오전 정보 오해의 소지가주고 싶지 않습니다. 그들은 논리적으로 큰 모듈을 분리하는 데 유용하게 보입니다.
굵은 글씨로 자신의 질문에 답을 얻지 못했습니까? 즉, 변수가 (또는 주로) 동일한 모듈에서 선언 된 루틴에 의해 사용되는 경우 * host-association *을 사용하고 많은 모듈에서 사용할 변수를 정의 할 때 * use-association *을 사용합니까? 그리고'public'과'private' 속성을 사용하여 변수를 포함한 모듈 엔티티에 대한 액세스를 제한 할 수 있다는 것을 잊지 마십시오. –
호스트 연관의 일부 측면, 특히 일부 서브 루틴이 부주의하게 변수를 수정할 수도 있기 때문에 굵은 텍스트가 질문에 답하지 않는다고 생각합니다. 그래서 예를 들어, 매개 변수에만 호스트 연결을 사용해야하는지 잘 모르겠습니다. 그러나 그 접근법에 대한 몇 가지 주장이 있습니다 (질문 참조). 대체로, 나는 무엇을 해야할지, 언제 할 것인지를 쉽게 모르며, 다른 사람들이 어떻게 보는지에 대한 약간의 정보를 얻기를 바라고 있습니다. 좀 더 이해하기 쉽지만 위험한 경로를 선택하거나 안전한 옵션을 찾으십시오. – ConfusedProgrammer
귀하의 이전 질문에 대한 내 의견은 내부 절차를 피하기위한 조언으로 해석되어서는 안됩니다. 나의 목표는 당신이 알고있는 명확하지 않았기 때문에 호스트 변수의 어떤 것도 args리스트에 선언 된 것뿐만 아니라 액세스 될 수 있다는 것을 지적하기 위해서였다. BTW,이 페이지의 오른쪽에있는 "관련"링크에 유용한 팁이 있습니다 ... –