IPB
ЛогинПароль:

> Внимание! Действует предмодерация

Подраздел FAQ (ЧАВО, ЧАстые ВОпросы) предназначен для размещения готовых рабочих программ, реализаций алгоритмов. Это нечто вроде справочника, он наполнялся в течение 2000х годов. Ваши вопросы, особенно просьбы решить задачу, не пройдут предмодерацию. Те, кто наполнял раздел, уже не заходят на форум, а с теми, кто на форуме сейчас, лучше начинать общение в других разделах. В частности, решение задач — здесь.

> Процедурные типы, параметры и переменные
сообщение
Сообщение #1


Гость






Процедурные типы и переменные

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

Например, становится возможным написать функцию интегрирования любой функции вида f(t) по схеме:
function Integral(LowerLimit, UpperLimit: Real;
Funct: FuncType): Real;
{
Описание локальных переменных процедуры
}
var t: Real;
begin
{
Численное интегрирование по t от LowerLimit до UpperLimit
функции Funct, причем для получения значения функции при
заданном аргументе t достаточно сделать вызов Funct(t).

Результат интегрирования возвращается как результат функции Integral
}
end;


Характерно, что синтаксис записи процедурного типа в точности совпадает с записью заголовка процедуры или функции, только опускается идентификатор после ключевого слова procedure или function. Приведем некоторые примеры описаний процедурного типа (Turbo/Borland Pascal не позволяет описывать функции, которые возвращают значения процедурного типа. Результат функции должен быть строкового, вещественного, целого, символьного, булевского типа, указателем или иметь перечислимый тип, определенный пользователем):
type
Proc = procedure;
SwapProc = procedure(var X, Y: Integer);
StrProc = procedure(S: String);
MathFunc = function(X: Real): Real;
DeviceFunc = function(var F: text): Integer;
MaxFunc = function(A, B: Real; F: MathFunc): Real;


Как видно из приведенных примеров, существует два процедурных типа: тип-процедура и тип-функция.

Имена параметров в описании процедурного типа играют чисто декоративную роль - на смысл описания они не влияют. Необходимыми являются только идентификаторы типов параметров и результатов (для функций).

В приведенном выше каркасе примера интегрирования есть одноместная функция F(t) возвращающая вещественное значение. Класс таких функций может описываться так:
type FuncType = function(t: Real): Real;


Тип, к которому могла бы принадлежать сама функция Integral, должен был бы выглядеть примерно так:
type
IntegralType = function(a, b: Real; f: FuncType): Real;


После объявления процедурного (или функционального) типа его можно использовать в описаниях параметров подпрограмм. И, конечно, необходимо написать те реальные процедуры и функции, которые будут передаваться как параметры. Требование к ним одно: они должны компилироваться в режиме {$F+}. Поскольку по умолчанию принят режим {$F-}, такие процедуры обрамляются парой соответствующих директив. Пример функции, которая принадлежит введенному выше типу FuncType:
{$F+}
function SinExp(tt: Real): Real;
begin
SinExp := Sin(tt) * Exp(tt)
end;
{$F-}

аналогичное описание с использованием директивы компилятора Far:
function SinExp(tt: Real): Real; far;
begin
SinExp := Sin(tt) * Exp(tt)
end;


Такая функция уже может быть подставлена в вызов функции численного интегрирования:
var x: Real;
...
x := Integral(0, 1, SinExp);

И мы получим в переменной X значение интеграла в пределах [0, 1].
Но не всякую функцию процедуру можно подставить в такой вызов. Существуют определенные правила.

Правила корректной работы с процедурными типами
  1. Подпрограмма, присваиваемая процедурной переменной должна быть оттранслирована в режиме ”дальнего вызова” (с использованием ключа компилятора {$F+} или директивы компилятора Far).
  2. Подпрограмма, присваиваемая процедурной переменной, не должна быть стандартной процедурой или функцией. Нельзя, например, напрямую взять интеграл функции синуса:
    x := Integral(0, 1, Sin);


    Это ограничение легко обойти, определив свою функцию:
    function MySin(R: Real): Real; far;
    begin
    MySin := Sin( R )
    end;
    ...
    begin
    ...
    x := Integral(0, 1, MySin);
    ...
    end.

  3. Подпрограмма, присваиваемая процедурной переменной, не может быть вложенной в другие подпрограммы.
  4. Подпрограмма, присваиваемая процедурной переменной, не может быть подпрограммой специального вида (interrupt или inline) из-за особенностей машинного представления.
Применение процедурного типа не ограничивается одним описанием параметров-процедур или функций. Если есть такой тип, то могут быть и переменные такого типа.
 К началу страницы 
+ Ответить 

Сообщений в этой теме


 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 29.03.2024 5:55
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name