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

Процедуры

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

Внутренние переменные

Внутренние переменные доступны и используются внутри процедур.

Внутренние переменные получившие инициализацию являются статическими, т.е. память выделяется на этапе компиляции (неявно обладают атрибутом static).

Атрибут automatic устанавливает переменные автоматическими, т.е. память выделяется во время работы программы.

program static_var

 call sub() ! M = 1
 call sub() ! M = 2
 call sub() ! M = 3

end


subroutine sub()
  integer :: M = 0
  M = M + 1
  write(*,*) M
end subroutine sub
program static_var

 call sub() ! M = 1
 call sub() ! M = 1
 call sub() ! M = 1

end

subroutine sub()
  integer , automatic :: M
  M = 0
  M = M + 1
  write(*,*) M
end subroutine sub

Передача параметров

Формальные параметры

  1. входные, intent(in)
  2. выходные, intent(out)
  3. входные/выходные, intent(inout)
subroutine sub(a,b,c)
  integer,   intent(in)    :: a
  real,      intent(out)   :: b
  character, intent(inout) :: c
  ...
end subroutine sub

По умолчанию все параметры имеют атрибут inout, т.к. передаются по ссылке.

Вид связи intent(in)

Принимают значение от соответствующего фактического параметра и не могут изменяться при выполнении процедуры.

Соответствующими фактическими параметрами могут быть выражения, переменные, значения, константы.

program param_in
  call sub(100)
end

subroutine sub(a)
  integer,   intent(in) :: a ! входной параметр
  ...
end subroutine sub

Вид связи intent(out)

Параметры передают свое значение соответствующему фактическому параметру и предназначены для вывода данных из процедуры.

Соответствующий фактический параметр должен быть переменной.

program param_out
  call sub(100) ! ошибка, ожидалась переменная
end

subroutine sub(a)
  integer,   intent(out) :: a ! выходной параметр
  ...
end subroutine sub

Вид связи intent(inout)

Параметры могут как принимать значения от фактического параметра, так и передавать данные в фактический параметр.

Соответствующие фактические параметры должны быть переменными.

program param_inout
  integer :: q = 80
  call sub(q)
end

subroutine sub(a)
  integer,   intent(inout) :: a ! входной/выходной 
  ...                           ! параметр
end subroutine sub

Optional параметры

Атрибут optional устанавливает формальные параметры необязательными.

Функция present проверяет присутствие необязательного параметра при вызове процедуры.

При отсутствии проверки функцией present возможны ошибки выполнения для параметров с видом связи intent(out, inout).

Процедура должна иметь явный интерфейс.

Optional параметры

program param_in
  real res
  res = logarithm(144.0,base = 12.0)
  write(*,*) res

CONTAINS 
real function logarithm(a, base)
  real, intent(in)    :: a
  real, intent(in), optional  :: base
  if (present(base)) then
    logarithm = log(a)/log(base)
  else
    logarithm = log10(a)
  end if
end function logarithm

END

Область видимости

Объекты1Объекты – переменные, типы данных, внутренние процедуры (для головной программы или внешней процедуры) описанные в головной программе доступны во внутренних процедурах, недоступны во внешних.

Объекты описанные во внутренней, внешней процедурах доступны только в них самих.

При совпадении имен объектов головной программы и внутренней или внешней процедур, объекты являются разными.


program array
 integer, parameter :: M = 10
 integer :: A(M) = [2,4,6,8,9,1,1,1,1,1]

 call PrintArray()

contains 
  subroutine PrintArray() ! нет формальных параметров
    integer k             ! доступ к массиву A
    do k = 1,M              ! из головной программы
      write(*,"(i6,\)") A(k)
    end do
    write(*,*)
  end subroutine PrintArray

END

Оператор interface

Почему при компиляции выдаётся ошибка?

program question
  write(*,*) middle(3.0,2.0)
END

real function middle(a,b)
  real a,b
  middle = (a+b)/2
end function middle

По умолчанию тип функции middleцелый. Функция объявлена как вещественная, но головная программа об этом "не знает".

Как указать головной программе про тип функции middle?

Определяет явно заданный интерфейс.

Используется для внешних процедур.

Внутренние процедуры обладают явно заданным интерфейсом.

interface
  тип имя_функции(формальные параметры)
  тип формальных параметров
  конец описания функции
end interface

Исправленная версия программы

program question

interface
  real function middle(a,b)
    real a,b
  end function middle
end interface

write(*,*) middle(3.0,2.0)

END

real function middle(a,b)
  real a,b
  middle = (a+b)/2
end function middle
< Лекция 5 || Лекция 6: 123 || Лекция 7 >