Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Глава 3_2.doc
Скачиваний:
25
Добавлен:
13.03.2016
Размер:
203.78 Кб
Скачать

Вызов процедуры Вызов процедуры-подпрограммы осуществляется отдельным оператором следующего вида:

CALL имя подпрограммы ([список фактических параметров])

Обращение к функции является операндом в выражении. Оно может присутствовать в правой части оператора присваивания. Например:

a = имя функции ([список фактических параметров])

Фактическими параметрами могут быть выражения, буквальные и именованные константы, простые переменные, массивы и их сечения, элемен­ты массивов, записи, элементы записей, строки, подстроки, процедуры и встроенные функции. Если фактический параметр является внешней процедурой, то он дол­жен в описании иметь атрибут EXTERNAL. Если же фактический параметр являет­ся встроенной процедурой, то он должен быть объявлен с атрибутом INTRINSIC.

Между формальными параметрами процедуры в описании и фактическими параметрами при обращении к ней должны выполняться правила соответствия:

- соответствие по количеству (сколько формальных параметров, столько же фактических);

- соответствие по последовательности: первый фактический параметр соответствует первому формальному, второй – второму и т.д.

- соответствие по типу: типы соответствующих параметров должны совпадать.

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

Program Treug1

real x1,y1,x2,y2,x3,y3,r

print*,"Введите: x1,y1,x2,y2,x3,y3"

read*,x1,y1,x2,y2,x3,y3 !(1,1)(2,2)(2,1)

r=S(x1,y1,x2,y2); print*,r !1.414214

r=S(x1,y1,x3,y3); print*,r !1.000000

r=S(x2,y2,x3,y3); print*,r !1.000000

contains

real function S(w1,z1,w2,z2)

real w1,z1,w2,z2

S=sqrt((w1-w2)**2+(z1-z2)**2)

end function S

end program flocal

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

Program Treug2

real x1,y1,x2,y2,x3,y3,r

print*,"Введите: x1,y1,x2,y2,x3,y3"

read*,x1,y1,x2,y2,x3,y3 !(1,1)(2,2)(2,1)

CALL S(x1,y1,x2,y2,r); print*,r !1.414214

CALL S(x1,y1,x3,y3,r); print*,r !1.000000

CALL S(x2,y2,x3,y3,r); print*,r !1.000000

end program Treug2

subroutine S(w1,z1,w2,z2, L)

real w1,z1,w2,z2, L

L=sqrt((w1-w2)**2+(z1-z2)**2)

end subroutine S

Рекурсивные процедуры

В математике рекурсивным называется определение любого понятия через самого себя. Классическим примером является определение факториала целого числа, большего или равного нулю.

Здесь функция факториал определена через факториал. Нетрудно понять справедливость такого определения. Для > 0

Вариант 0! = 1 является тривиальным. Но это опорное значение, от которого начинается «раскручивание» всех последующих значений факториала:

1! = 1 * 0! =1*1 =1; 2! = 2 * 1 = 2; 3! = 3 * 2! = 6 и т.д.

Рассмотрим процедуру-функцию, использующую в своем описании приведенную выше рекурсивную формулу.

Recursive function ifact(n) result (fav)

Integer fav, n

If(n=0) then

Fav=1

Else

Fav=n*ifact(n-1)

Endif

End

Тип результата рекурсивной функции может быть задан и следующими двумя способами:

recursive integer function ifact(n) result (fav)

integer recursive function ifact(n) result (fav)

В рекурсивно определенной функции обязательно должна использоваться переменная для результата. В данном примере это переменная fav.

Основная программа, которая использует внешнюю функцию ifact для вычисления величины K!, имеет следующий вид:

Program factorial

Integer K, ifact

Print*, ‘Введите К’

Read*, K

Write(*,’(2X,I2,A,I6)’) K,’!=’, ifact(K)

end

Пусть в основной программе в целую переменную К вводится число 3. При вычислении функции ifact с аргументом 3 произойдет повторное обращение к функции ifact(2). Это обращение потребует вычисления ifact(1). И наконец, при вычислении ifact(0) будет получен числовой результат 1. Затем цепочка вычислений раскрутится в обратном порядке:

ifact (1) = 1 * ifact (0) = 1 ,

ifact(2) = 2*ifact(1) = 2 ,

ifact(3) = 3*ifact(2) = 6.

Последовательность рекурсивных обращений к функции должна обязательно выходить на определенное значение. А весь маршрут последовательных вхождений машина запоминает в специальной области памяти, называемой стеком. Таким образом, выполнение рекурсивной функции происходит в два этапа: прямой ход –– заполнение стека; обратный ход –– цепочка вычислений по обратному маршруту, сохраненному в стеке.

Использование рекурсивных функций — красивый прием с точки зрения программистской эстетики. Однако этот путь не всегда самый рациональный. Рассмотренную задачу с n! можно решить так:

F= 1

do I= 1, N

F= F*I

enddo

Очевидно, что такой вариант программы будет работать быстрее, чем рекурсивный. И в том случае, когда важно сокращение времени выполнения программы, следует отдать предпочтение последнему варианту.