Фортран - Процедуры
А procedureэто группа операторов, которые выполняют четко определенную задачу и могут быть вызваны из вашей программы. Информация (или данные) передаются вызывающей программе в процедуру в качестве аргументов.
Есть два типа процедур -
- Functions
- Subroutines
Функция
Функция - это процедура, которая возвращает одно количество. Функция не должна изменять свои аргументы.
Возвращенное количество известно как function value, и обозначается именем функции.
Syntax
Синтаксис функции следующий -
function name(arg1, arg2, ....)
[declarations, including those for the arguments]
[executable statements]
end function [name]
В следующем примере демонстрируется функция с именем area_of_circle. Он вычисляет площадь круга радиусом r.
program calling_func
real :: a
a = area_of_circle(2.0)
Print *, "The area of a circle with radius 2.0 is"
Print *, a
end program calling_func
! this function computes the area of a circle with radius r
function area_of_circle (r)
! function result
implicit none
! dummy arguments
real :: area_of_circle
! local variables
real :: r
real :: pi
pi = 4 * atan (1.0)
area_of_circle = pi * r**2
end function area_of_circle
Когда вы компилируете и выполняете вышеуказанную программу, она дает следующий результат:
The area of a circle with radius 2.0 is
12.5663710
Обратите внимание, что -
Вы должны указать implicit none как в основной программе, так и в самой процедуре.
Аргумент r в вызываемой функции называется dummy argument.
Вариант результата
Если вы хотите, чтобы возвращаемое значение сохранялось под другим именем, чем имя функции, вы можете использовать result вариант.
Вы можете указать имя возвращаемой переменной как -
function name(arg1, arg2, ....) result (return_var_name)
[declarations, including those for the arguments]
[executable statements]
end function [name]
Подпрограмма
Подпрограмма не возвращает значения, но может изменять свои аргументы.
Syntax
subroutine name(arg1, arg2, ....)
[declarations, including those for the arguments]
[executable statements]
end subroutine [name]
Вызов подпрограммы
Вам нужно вызвать подпрограмму, используя call заявление.
В следующем примере демонстрируется определение и использование подпрограммы swap, которая изменяет значения своих аргументов.
program calling_func
implicit none
real :: a, b
a = 2.0
b = 3.0
Print *, "Before calling swap"
Print *, "a = ", a
Print *, "b = ", b
call swap(a, b)
Print *, "After calling swap"
Print *, "a = ", a
Print *, "b = ", b
end program calling_func
subroutine swap(x, y)
implicit none
real :: x, y, temp
temp = x
x = y
y = temp
end subroutine swap
Когда вы компилируете и выполняете вышеуказанную программу, она дает следующий результат:
Before calling swap
a = 2.00000000
b = 3.00000000
After calling swap
a = 3.00000000
b = 2.00000000
Определение цели аргументов
Атрибут intent позволяет указать намерение, с которым аргументы используются в процедуре. В следующей таблице представлены значения атрибута намерения -
Значение | Используется в качестве | Объяснение |
---|---|---|
в | намерение (в) | Используется как входные значения, не изменяется в функции |
из | намерение (выход) | Используемые как выходные значения, они перезаписываются |
inout | намерение (inout) | Аргументы используются и перезаписываются |
Следующий пример демонстрирует концепцию -
program calling_func
implicit none
real :: x, y, z, disc
x = 1.0
y = 5.0
z = 2.0
call intent_example(x, y, z, disc)
Print *, "The value of the discriminant is"
Print *, disc
end program calling_func
subroutine intent_example (a, b, c, d)
implicit none
! dummy arguments
real, intent (in) :: a
real, intent (in) :: b
real, intent (in) :: c
real, intent (out) :: d
d = b * b - 4.0 * a * c
end subroutine intent_example
Когда вы компилируете и выполняете вышеуказанную программу, она дает следующий результат:
The value of the discriminant is
17.0000000
Рекурсивные процедуры
Рекурсия возникает, когда языки программирования позволяют вызывать функцию внутри той же функции. Это называется рекурсивным вызовом функции.
Когда процедура вызывает себя прямо или косвенно, это называется рекурсивной процедурой. Вы должны объявить этот тип процедур, поставив перед словомrecursive перед его объявлением.
Когда функция используется рекурсивно, result должна использоваться опция.
Ниже приведен пример, который вычисляет факториал для данного числа с помощью рекурсивной процедуры.
program calling_func
implicit none
integer :: i, f
i = 15
Print *, "The value of factorial 15 is"
f = myfactorial(15)
Print *, f
end program calling_func
! computes the factorial of n (n!)
recursive function myfactorial (n) result (fac)
! function result
implicit none
! dummy arguments
integer :: fac
integer, intent (in) :: n
select case (n)
case (0:1)
fac = 1
case default
fac = n * myfactorial (n-1)
end select
end function myfactorial
Внутренние процедуры
Когда процедура содержится в программе, она называется внутренней процедурой программы. Синтаксис для содержания внутренней процедуры следующий:
program program_name
implicit none
! type declaration statements
! executable statements
. . .
contains
! internal procedures
. . .
end program program_name
Следующий пример демонстрирует концепцию -
program mainprog
implicit none
real :: a, b
a = 2.0
b = 3.0
Print *, "Before calling swap"
Print *, "a = ", a
Print *, "b = ", b
call swap(a, b)
Print *, "After calling swap"
Print *, "a = ", a
Print *, "b = ", b
contains
subroutine swap(x, y)
real :: x, y, temp
temp = x
x = y
y = temp
end subroutine swap
end program mainprog
Когда вы компилируете и выполняете вышеуказанную программу, она дает следующий результат:
Before calling swap
a = 2.00000000
b = 3.00000000
After calling swap
a = 3.00000000
b = 2.00000000