Томский государственный университет систем управления и радиоэлектроники
Опубликован: 01.11.2012 | Доступ: свободный | Студентов: 651 / 76 | Длительность: 06:01:00
Лекция 6:

Процедуры

< Лекция 5 || Лекция 6: 123 || Лекция 7 >

Оператор 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

функции подставляемые вместо функции fun

p(x)=x+ sin\ x\\
q(x)=x- cos\ x\\
s(x)=\surd x+x
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 объявляет процедуру чистой.

Для чистых процедур характерно

  1. все формальные параметры функций имеют вид связи intent(in);
  2. все формальные параметры подпрограмм имеют вид связи intent(in, out или inout);
  3. локальные переменные не имеют атрибут save, не могут быть инициализированы в операторах объявления.
  4. отсутствуют операторы В/В, 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
< Лекция 5 || Лекция 6: 123 || Лекция 7 >