Процедуры
Оператор return
Вернуть управление вызывающей процедуре или головной программе.
program break_function write(*,*) div(3,0) contains integer function div(a,b) integer a,b if (b == 0) then div = 0 write(*,*) "ERROR divided by zero" return else div = a/b end if end function div END
Процедуры как параметры
Универсализация процедур.
![f(x)=\sum^{100}_{k=1} fun (k) \cdot x^k](/sites/default/files/tex_cache/78ca5421e26687172a35fb29981d4434.png)
функции подставляемые вместо функции fun
![p(x)=x+ sin\ x\\
q(x)=x- cos\ x\\
s(x)=\surd x+x](/sites/default/files/tex_cache/ea3c11449282438343ab6487f1890a98.png)
program param_funct external p, q, s write(*,*) f(0.5, p) ! p(x) - фактический параметр write(*,*) f(0.7, q) ! q(x) - фактический параметр write(*,*) f(1.2, s) ! s(x) - фактический параметр end !******************************** real function q(x) ! ---------- функция q(x) real x q = x-cos(x) end function q real function s(x) ! ---------- функция s(x) real x s = sqrt(x)+x end function s
real function p(x) ! ---------- функция p(x) real x p = sin(x)+x end function p real function f(x, fun) interface ! --- явный интерфейс для внешних функций real function fun(x) real x end function fun end interface real x integer k f = 0.0 do k = 1,100 f = fun(REAL(k))*x**k+f end do end function f
Оператор external объявляет, что перечисленные внешние процедуры передаются как параметры.
Если хотим передавать стандартные функции как параметры, то нет смысла писать
program param_funct external mysin write(*,*) f(0.5, mysin) end !******************************** real function mysin(x) ! ---------- функция q(x) real x q = sin(x) end function mysin
Оператор intrinsic объявляет, что перечисленные стандартные процедуры передаются как параметры.
program param_funct intrinsic sin write(*,*) f(0.5, sin) end ...
Вместо указания функции в операторе external можно использовать блок interface.
интерфейс фактического параметра-функции
program param_funct interface real function p(x) real x end function p end interface
интерфейс формального параметра-функции
interface real function f(x, fun) interface real function fun(x) real x end function fun end interface real x end function end interface ...
Рекурсивные процедуры
Процедура вызывающая сама себя. recursive – объявление рекурсивной процедуры.
proc ---> proc ---> proc --->
proc ---> sub ---> proc ---> sub --->
Обязательна проверка окончания рекурсивного вызова.
Рекурсивный вывод последовательности чисел.
program recurse call Number(10) ! contains recursive subroutine Number(N) integer N write(*,*) " N = ", N if (N == 1) return ! точка останова call Number(N-1) ! рекурсивный вызов end subroutine Number end
Результирующая переменная, предложение result.
program fact write(*,*) factorial(10) contains recursive function factorial(p) result(k) integer, intent(in) :: p integer k if (p == 1) then k = 1 else k = p * factorial(p - 1) end if end function end
Чистые процедуры
Чистые процедуры – процедуры без побочных эффектов
program side_effect real :: s = 10.0 write(*,*) (f(s)+f(s))/2.0 ! ожидалось 100 ! результат 110.5 contains real function f(x) real x f = x*x x = x+1 end function f end
Ключевое слово pure объявляет процедуру чистой.
Для чистых процедур характерно
- все формальные параметры функций имеют вид связи intent(in);
- все формальные параметры подпрограмм имеют вид связи intent(in, out или inout);
- локальные переменные не имеют атрибут save, не могут быть инициализированы в операторах объявления.
- отсутствуют операторы В/В, stop.
Все встроенные функции являются чистыми.
В операторе forall используются только чистые процедуры.
PROGRAM PURE_FORALL real :: A(10) = -1.0 integer i forall (i = 1:5, A(i) < 0) A(i) = F(A(i)) end forall contains real pure function f(x) real, intent (in) :: x f = x*x end function f END
Элементные процедуры
Элементные процедуры могут иметь в качестве фактических параметров как скаляры так и массивы.
Элементные функции – чистые функции, имеющие только скалярные формальные параметры с видом связи intent(in).
Фактическими параметрами могут быть согласованные массивы.
Пример.
Функции sin, cos, exp, abs - элементные.
Можно записывать:
- sin(2.0), sin(a), где a – скаляр
- cos(B), abs(A), где A, B - массивы
Ключевое слово elemental объявляет процедуру элементной.
program ELEMENTAL_FUNC real :: A(10) = [1,2,3,4,5,6,7,8,9,0] write(*,"(10f5.1)") f(A) contains real elemental function f(x) real, intent (in) :: x f = x*x end function f end