Fortran
절차 - 함수 및 서브 루틴
수색…
비고
함수 및 서브 루틴 은 모듈 과 함께 프로그램 을 단위로 나누는 도구입니다. 이것은 프로그램을 더 읽기 쉽고 관리하기 쉽게 만듭니다. 이러한 각 단위는 코드의 일부로 생각할 수 있으며, 이상적으로는 컴파일하고 별도로 테스트 할 수 있습니다. 주 프로그램 (들)은 작업을 수행하기 위해 그러한 서브 프로그램 (함수 또는 서브 루틴)을 호출 (또는 호출) 할 수 있습니다.
함수 및 서브 루틴은 다음과 같은 의미에서 다릅니다.
- 함수 는 단일 객체를 반환하고 일반적으로 인수의 값을 변경하지 않습니다 (즉, 함수는 마치 수학 함수처럼 작동합니다!).
- 서브 루틴은 대개 더 복잡한 작업을 수행하며 일반적으로 인수 (있는 경우)와 다른 변수 (예 : 서브 루틴이 포함 된 모듈에서 선언 된 변수)를 변경합니다.
함수와 서브 루틴은 집합 적으로 프로 시저 의 이름 아래에 있습니다 . (기술적 절차로하더라도의 동의어 "호출"로 우리가 동사를 사용하는 다음의 '통화' call
혼성있는 subroutine
반면들, function
들 할당 또는 표현식에서와 같이 오른쪽으로 표시).
함수 구문
여러 가지 유형의 구문을 사용하여 함수를 작성할 수 있습니다.
function name()
integer name
name = 42
end function
integer function name()
name = 42
end function
function name() result(res)
integer res
res = 42
end function
함수는 함수 결과를 통해 값을 반환합니다. 함수 명령문에 result
절이 없으면 함수의 결과는 함수와 동일한 이름을가집니다. result
로 함수 결과는 결과에 의해 주어진 result
입니다. 위의 처음 두 예제에서 함수 결과는 name
. res
의해 세 번째.
함수 결과는 함수 실행 중에 정의되어야합니다.
함수는 몇 가지 특별한 접두사를 사용할 수 있습니다.
순수 함수는이 함수가 부작용이 없음을 의미합니다.
pure real function square(x)
real, intent(in) :: x
square = x * x
end function
원소 스칼라 함수 연산자로 정의되지만이 기능 소자 와이즈인가 될 경우 실제 인수로 배열하여 호출 될 수있다. impure
접두어 (Fortran 2008에서 소개 됨)가 지정되어 있지 않으면 원소 함수는 순수한 함수이기도합니다.
elemental real function square(x)
real, intent(in) :: x
square = x * x
end function
return 문
return
문은 함수와 서브 루틴을 종료하는 데 사용될 수 있습니다. 다른 많은 프로그래밍 언어와 달리 반환 값을 설정하는 데 사용되지 않습니다.
real function f(x)
real, intent(in) :: x
integer :: i
f = x
do i = 1, 10
f = sqrt(f) - 1.0
if (f < 0) then
f = -1000.
return
end if
end do
end function
이 함수는 반복 계산을 수행합니다. f
값이 음수가되면 함수는 -1000을 반환합니다.
재귀 프로 시저
Fortran 함수와 서브 루틴은 직접적으로 또는 간접적으로 자신을 다시 호출해야하는 경우 재귀 적으로 명시 적으로 선언해야합니다. 따라서, 피보나치 시리즈의 재귀 구현은 다음과 같이 보일 수 있습니다 :
recursive function fibonacci(term) result(fibo)
integer, intent(in) :: term
integer :: fibo
if (term <= 1) then
fibo = 1
else
fibo = fibonacci(term-1) + fibonacci(term-2)
end if
end function fibonacci
계승을 계산하는 또 다른 예는 다음과 같습니다.
recursive function factorial(n) result(f)
integer :: f
integer, intent(in) :: n
if(n == 0) then
f = 1
else
f = n * f(n-1)
end if
end function factorial
함수를 직접 재귀 적으로 참조하려면 그 정의가 result
접미어를 사용해야합니다. 함수가 recursive
거나 elemental
적일 수는 없습니다.
더미 인수의 의도
서브 루틴 또는 함수에서 가명 인수의 intent
속성은 의도 된 사용을 선언합니다. 구문은 다음 중 하나입니다.
intent(IN)
intent(OUT)
intent(INOUT)
예를 들어, 다음 함수를 고려하십시오.
real function f(x)
real, intent(IN) :: x
f = x*x
end function
intent(IN)
는 (포인터가 아닌) 더미 인수 x
가 함수 또는 함수 초기화를 통해 정의되거나 정의되지 않을 수 있음을 지정합니다. 포인터 가짜 인수가 intent(IN)
속성을 갖는 경우, 이것은 연관에 적용됩니다.
포인터가 아닌 임시 인수에 대한 intent(OUT)
는 임시 인수가 서브 프로그램의 호출시 정의되지 않고 (기본 초기화로 파생 된 유형의 구성 요소 제외) 수행 중에 설정됨을 의미합니다. 더미 인수로 전달 된 실제 인수는 정의 가능해야합니다. 명명 된 상수 또는 리터럴 상수 또는 표현식 전달은 허용되지 않습니다.
이전과 마찬가지로 포인터 더미 인수가 intent(OUT)
이면 포인터의 연관 상태가 정의되지 않습니다. 실제 인수는 포인터 변수 여야합니다.
intent(INOUT)
는 실제 인수가 정의 가능하고 프로 시저에서 데이터를 전달하고 반환하는 데 적합 함을 지정합니다.
마지막으로, 가짜 인수는 intent
특성이 없을 수 있습니다. 그러한 가짜 인수는 전달 된 실제 인수에 의해 사용이 제한됩니다.
예를 들어,
integer :: i = 0
call sub(i, .TRUE.)
call sub(1, .FALSE.)
end
subroutine sub(i, update)
integer i
logical, intent(in) :: update
if (update) i = i+1
end subroutine
인수는 i
더 가질 수 없습니다 intent
메인 프로그램의 서브 루틴 호출을 모두 허용 속성을.
프로 시저 참조
유용한 함수 또는 서브 루틴을 참조해야합니다. call
문에서 서브 루틴이 참조됩니다.
call sub(...)
표현식 내의 함수. 다른 많은 언어와 달리 표현식은 완전한 명령문을 구성하지 않으므로 함수 참조는 대개 할당 문에 표시되거나 다른 방식으로 사용됩니다.
x = func(...)
y = 1 + 2*func(...)
참조되는 프로 시저를 지정하는 세 가지 방법이 있습니다.
- 프로 시저 또는 프로 시저 포인터의 이름
- 파생 된 유형 객체의 프로 시저 구성 요소
- 형 바인딩 프로 바이더 바인딩 명
첫 번째는 다음과 같이 볼 수 있습니다.
procedure(), pointer :: sub_ptr=>sub
call sub() ! With no argument list the parentheses are optional
call sub_ptr()
end
subroutine sub()
end subroutine
마지막 두 개는
module mod
type t
procedure(sub), pointer, nopass :: sub_ptr=>sub
contains
procedure, nopass :: sub
end type
contains
subroutine sub()
end subroutine
end module
use mod
type(t) x
call x%sub_ptr() ! Procedure component
call x%sub() ! Binding name
end
더미 인수가있는 프로 시저의 경우, 참조에 해당 실제 인수가 필요하지만 선택적 더미 인수는 제공되지 않을 수 있습니다.
서브 루틴 고려
subroutine sub(a, b, c)
integer a, b
integer, optional :: c
end subroutine
이것은 다음 두 가지 방법으로 참조 될 수 있습니다.
call sub(1, 2, 3) ! Passing to the optional dummy c
call sub(1, 2) ! Not passing to the optional dummy c
이것은 소위 위치 참조입니다. 실제 인수는 인수 목록의 위치를 기준으로 연결됩니다. 여기서 더미 a
는 1
과 연관되고 b
는 2
와 c
(지정된 경우)는 3
과 연관됩니다.
또는, 프로 시저가 명시 적 인터페이스를 사용할 수있는 경우 키워드 참조가 사용될 수 있습니다
call sub(a=1, b=2, c=3)
call sub(a=1, b=2)
이는 위와 동일합니다.
그러나 키워드를 사용하면 실제 인수가 임의의 순서로 제공 될 수 있습니다
call sub(b=2, c=3, a=1)
call sub(b=2, a=1)
위치 및 키워드 참조가 모두 사용될 수 있습니다
call sub(1, c=3, b=2)
단, 키워드가 처음 나타난 후 모든 인수에 대해 키워드가 제공되는 한
call sub(b=2, 1, 3) ! Not valid: all keywords must be specified
키워드 참조의 가치는 여러 개의 선택적 더미 인수가있을 때 특히 두드러집니다. 위의 서브 루틴 정의에서 b
가 선택적이라면 아래에서 볼 수 있습니다
call sub(1, c=3) ! Optional b is not passed
유형이 바인드 된 프로시 듀어 또는 전달 된 인수가있는 구성 요소 프로시 듀어 포인터에 대한 인수 목록은 개별적으로 고려됩니다.