Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Лекция 11. Подпрограммы-функции.

Читайте также:
  1. Белье – Новая коллекция
  2. ВВОДНАЯ ЛЕКЦИЯ
  3. ВОСЬМАЯ ЛЕКЦИЯ
  4. ВТОРАЯ ЛЕКЦИЯ
  5. ДВЕНАДЦАТАЯ ЛЕКЦИЯ
  6. ДЕВЯТАЯ ЛЕКЦИЯ
  7. ДЕСЯТАЯ ЛЕКЦИЯ

Побочный эффект

Функция – это подпрограмма, возвращающая обязательное значение. Общий вид определения функции:

function Имя_функции(S): TF;

Разделы описаний

Begin

Основной блок функции

End;

Здесь S обозначает список описаний формальных параметров, который может отсутствовать – тогда опускаются и скобки. TF – имя типа значения функции. В качестве типа функции TF используются простые типы, а из сложных – разрешены только строковый и ссылочный типы. Разделы описаний и основной блок аналогичны таким же разделам процедуры. Возвращаемое значение функции связывается с её именем, поэтому среди инструкций основного блока должно выполниться хотя бы одно присваивание вида

Имя_функции := выражение_типа_TF

Таким образом, самая короткая функция выглядит так:

function Имя_функции: TF;

Begin

Имя_функции := выражение_типа_TF

End;

Обращение к такой функции состоит только из одного имени функции.

При указании имени функции в каких-либо выражениях в её основном блоке в качестве простой переменной – это воспринимается как попытка рекурсивного вызова (смотри далее Тему "Рекурсия").

Всё сказанное о параметрах процедуры остаётся верным и для функции, только использование передачи параметров по ссылке носит название побочного эффекта. В этом случае, кроме основного обязательного значения функции, через такие параметры могут вернуться дополнительные значения. Для упрощения логики программы и избежания труднообнаружимых ошибок побочный эффект рекомендуется применять только при крайней необходимости. В следующем примере из-за побочного эффекта на экран выдаётся значение 10 вместо (по-видимому, ожидаемого) значения 9. Здесь функция F вычисляется первой и успевает модифицировать второе слагаемое – переменную A – до вычисления суммы:

function F(var X: Integer): Integer;

Begin

X := X + 1;

F := X*X*X

end; {F}

Var

A: Integer;

Begin

A := 1;

WriteLn(F(A) + A)

End.

 

Если глобальная переменная доступна в какой-то функции и модифицируется ею, то это также является побочным эффектом.

 

Лекция 12. Рекурсия.

Модули.

Процедурный (функциональный) тип – это множество однотипных либо процедур, либо функций. Определение процедурного типа имеет вид:

Type

TP1 = procedure (S);

а определение функционального типа:

TF1 = function (S): TF;

здесь TP1, TF1 – имя того или иного типа, S – обычный список описаний формальных параметров, который может отсутствовать – тогда опускаются и скобки. TF – имя типа значения функции. Принадлежность реальной процедуры или функции определённому типу устанавливается по типам в списке S, а для функций – ещё и по типу TF. Имена формальных параметров могут не совпадать с именами в определении процедурного типа – обязательным является совпадение их типов.

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

В Турбо Паскале приняты две модели памятидальняя и ближняя. Компилятор по умолчанию придерживается ближней модели памяти для простых программ. В этом случае машинный код получается более быстрый по исполнению и занимает меньший объём памяти. Однако для процедурного типа по умолчанию используется дальняя модель. Поэтому для полного соответствия подпрограммы процедурному типу она должна определяться в дальней модели памяти.

Для этого после её заголовка ставится стандартная директива far; (точка с запятой – обязательно!). Возможен и другой способ определения дальней модели памяти уже для целой группы подпрограмм: перед определением первой подпрограммы ставится директива компилятору {$F+} (включить компиляцию дальней модели). После конца текста последней подпрограммы можно, наоборот – поставить директиву {$F-} (возобновить компиляцию ближней модели).

Процедурный тип обычно необходим при передаче имён одних подпрограмм в качестве параметров других подпрограмм. Например, в задаче численного нахождения определённого интеграла от какой-то функции удобнее запрограммировать подынтегральную функцию отдельно и передавать её имя в качестве параметра. Тогда подпрограмма нахождения интеграла получает свойство массовости, то есть не привязана к конкретной функции. И в этом случае передаваемая подпрограмма должна быть откомпилирована в дальней модели памяти. Запрещается в качестве параметра передавать имя стандартной функции, в этом случае можно написать свою вспомогательную функцию и в ней обратиться к стандартной, а передавать имя вспомогательной функции.

Рекурсия – это обращение к подпрограмме из тела самой этой же подпрограммы. В языке Паскаль рекурсия разрешена. Рекурсивный алгоритм выглядит изящней при решении математических задач, сама формулировка которых имеет рекурсивный характер. В этом случае задача может быть разложена на совокупность подзадач того же типа, но меньшей размерности. Классический пример – вычисление факториала: N! = N*(N - 1)! для
N > 0 и 0! = 1! = 1. Здесь исходная задача размерности N разложена на произведение N и решения подзадачи размерности N - 1.

Методика создания рекурсивных алгоритмов содержит три этапа:

1) параметризация задачи;

2) поиск тривиального случая и его решение;

3) декомпозиция общего случая.

При каждом вызове подпрограммы её локальные переменные и адрес возврата из подпрограммы заносятся в специальную область памяти, называемую стеком. По окончании выполнения подпрограммы и выходе из неё эта область стека освобождается. В случае рекурсивного вызова локальная память не освобождается, а впадает в "зимнюю спячку", в стеке выделяется новая область под новые значения локальных переменных и новый адрес возврата. Доступ к стеку производится по принципу "последним пришёл – первым ушёл" (Last In, First Out – LIFO), поэтому при выходе из подпрограммы возврат производится в точку её последнего вызова. Таким образом, организация стека обеспечивает реализацию рекурсии.

Рекурсия может быть косвенной: подпрограмма A вызывает подпрограмму B, а та, в свою очередь, вызывает A. В этом случае нарушается принцип сильной типизации языка Паскаль: подпрограмма должна быть определена до обращения к ней. В такой ситуации выносят заголовок подпрограммы, определённой ниже, перед первой подпрограммой, а вместо тела, после заголовка, указывают стандартную директиву forward; (точка с запятой – обязательно!)

Модуль – это автономно компилируемая программная единица, включающая в себя любые компоненты раздела описаний (обычно, прежде всего – подпрограммы) и, возможно, какие-то инструкции. Модуль, в отличие от программы, не может быть запущен на выполнение самостоятельно: он может только участвовать в построении программы или другого модуля.

Текст модуля размещается в отдельном.pas файле, например gauss.pas. Результатом компиляции модуля является двоичный файл с расширением.tpu (Turbo Pascal Unit), например gauss.tpu. Чтобы подключить модуль к программе или к другому модулю, необходимо указать имя модуля в соответствующем разделе uses.

Общий вид модуля:

unit Имя_модуля;


Дата добавления: 2015-07-15; просмотров: 156 | Нарушение авторских прав


Читайте в этой же книге: Глоссарий | Краткий курс лекций | Хранение информации | Классификация структур данных | Операции над структурами данных | Операции. Выражения | Лекция 3 Структура программы. | Лекция 13. Ссылочный тип. | Лекция 14. Алгоритмы поиска и выборки. | Бинарный поиск |
<== предыдущая страница | следующая страница ==>
Безусловного перехода,| Interface

mybiblioteka.su - 2015-2024 год. (0.008 сек.)