![]() |
![]() |
volvo |
![]()
Сообщение
#1
|
Гость ![]() |
Процедурные типы и переменные
Отличительной особенностью Турбо Паскаля является разрешение передавать в процедуры и функции имена других подпрограмм, оформляя их как параметры. И точно так же, как передается значение, может передаваться некая функция его обработки. Особенно важным это становится при программной реализации алгоритмов вычислительной математики. Например, становится возможным написать функцию интегрирования любой функции вида f(t) по схеме: function Integral(LowerLimit, UpperLimit: Real; Характерно, что синтаксис записи процедурного типа в точности совпадает с записью заголовка процедуры или функции, только опускается идентификатор после ключевого слова procedure или function. Приведем некоторые примеры описаний процедурного типа (Turbo/Borland Pascal не позволяет описывать функции, которые возвращают значения процедурного типа. Результат функции должен быть строкового, вещественного, целого, символьного, булевского типа, указателем или иметь перечислимый тип, определенный пользователем): type Как видно из приведенных примеров, существует два процедурных типа: тип-процедура и тип-функция. Имена параметров в описании процедурного типа играют чисто декоративную роль - на смысл описания они не влияют. Необходимыми являются только идентификаторы типов параметров и результатов (для функций). В приведенном выше каркасе примера интегрирования есть одноместная функция F(t) возвращающая вещественное значение. Класс таких функций может описываться так: type FuncType = function(t: Real): Real; Тип, к которому могла бы принадлежать сама функция Integral, должен был бы выглядеть примерно так: type После объявления процедурного (или функционального) типа его можно использовать в описаниях параметров подпрограмм. И, конечно, необходимо написать те реальные процедуры и функции, которые будут передаваться как параметры. Требование к ним одно: они должны компилироваться в режиме {$F+}. Поскольку по умолчанию принят режим {$F-}, такие процедуры обрамляются парой соответствующих директив. Пример функции, которая принадлежит введенному выше типу FuncType: {$F+} аналогичное описание с использованием директивы компилятора Far: function SinExp(tt: Real): Real; far; Такая функция уже может быть подставлена в вызов функции численного интегрирования: var x: Real; И мы получим в переменной X значение интеграла в пределах [0, 1]. Но не всякую функцию процедуру можно подставить в такой вызов. Существуют определенные правила. Правила корректной работы с процедурными типами
|
![]() ![]() |
volvo |
![]()
Сообщение
#2
|
Гость ![]() |
В качестве примера для работы с функциональными (процедурными) типами рассмотрим создание функции для сортировки массива одним из известных методов (подробнее о методах сортировки - смотреть здесь)...
Целью данного примера будет создать такую процедуру, в которую пользователь мог бы передать как необходимый ему метод сортировки, так и ее направление (в возрастающем/убывающем порядке), и получить на выходе отсортированный массив. Для этого понадобится создать перечисление, содержащее названия реализованных методов сортировки, и каждому из этих названий поставить в соответствие реальную процедуру сортировки этим методом. Перечисление будет иметь вид: Type Поставить в соответствие каждому имени реальную процедуру сортировки можно, пользуясь типизированными константами (ведь если существует процедурный тип, и даже процедурные переменные, то могут быть описаны и типизированные константы этого типа). Предположим, что сами процедуры сортировок уже написаны (при этом обратите внимание на замену операции сравнения элементов на функцию для возможности реализации как восходящей, так и нисходящей сортировки одной и той же процедурой), и нужно только организовать соответствие между ними и перечислением имен. Это делается так: Procedure Bubble... Теперь при вызове: sortProc[srBubble]({список параметров для процедуры Bubble}) мы фактически вызываем процедуру: Bubble({список параметров для процедуры Bubble}) Единственное ограничение - все процедуры сортировки, которые будут использоваться, должны иметь одинаковый список формальных параметров... При переносе в модуль желательно делать доступными пользователю только те, процедуры (функции) и переменные, которые ему действительно нужны. Так появилась идея "скрыть" от пользователя реализацию функций сравнения элементов массива: Type (т.е. перенести их в раздел Implementation), но для того, чтобы он по-прежнему мог выбирать направление сортировки, ввести такое перечисление: Type и в разделе Inplementation также воспользоваться массивом функций: Const Таким образом, искомая функция сортировки по требованию пользователя может быть описана так: Procedure SuperSort(Var arr: arrType; n: Integer; а использовать ее можно следующим образом: Uses SortUnit; Реализация модуля, описанного выше содержит одну процедуру: Procedure SuperSort(Var arr: Array Of TType; n: Integer; где: arr - сортируемый массив n - размер сортируемого массива Style - вид сортировки, который надо применить может принимать значения: Цитата srBubble - пузырьковая сортировка srInsert - сортировка методом "простой вставки" srMerge - сортировка слияниями srHoarFirst - первый вариант быстрой сортировки Хоара srHoarSecond - второй вариант быстрой сортировки Хоара srHeap - пирамидальная сортировка Order - направление сортировки: Цитата orAscending - по возрастанию orDescending - по убыванию Для того, чтобы заставить этот модуль работать с другим встроенным типом данных Паскаля (например, с типом Double) достаточно изменить Type на Type Присоединенный файл содержит модуль с реализацией данной процедуры Прикрепленные файлы ![]() |
![]() ![]() |
![]() |
Текстовая версия | 27.07.2025 8:34 |