Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Информатика 2 семестр.doc
Скачиваний:
2
Добавлен:
01.04.2025
Размер:
609.28 Кб
Скачать

1.3.2. Параметры процедурного типа

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

Type

<Имя> = procedure (<Список формальных параметров>);

<Имя> = function (<Список формальных параметров>) : <Тип_результата>;

Ниже приводятся примеры описания.

func = function (x, y : real) : real;

proc = procedure (var v : vector; n : byte);

tip = procedure;

К типу func относятся все функции, имеющие два формальных параметра-значения вещественного типа и возвращающие результат такого же типа (например, функция f = x2 + y3 + 1). К типу proc относятся все процедуры, имеющие один формальный параметр-переменную типа vector (тип должен быть объявлен заранее) и один параметр-значение типа byte (например, рассмотренная выше процедура Vvod). К типу tip относятся все процедуры, не имеющие формальных параметров.

Существуют следующие правила использования подпрограмм в качестве параметров процедурного типа:

  1. подпрограммы должны компилироваться с ключом {$F+} или иметь директиву far;

  2. они не должны быть стандартными подпрограммами;

  3. они не должны объявляться внутри других подпрограмм;

  4. подпрограммы не должны иметь директив inline или interrupt.

Поясним суть наложенных на подпрограммы ограничений. Первое требование связано с организацией памяти компьютера в виде сегментов по 64 килобайта. Абсолютный адрес в памяти компьютера любого объекта программы (в том числе и подпрограммы) складывается из номера сегмента и номера байта в сегменте. Последний называют смещением или «ближним» адресом (по-английски - near). Абсолютный адрес - это «дальний» (far) адрес. Ключ компиляции {$F+} действует до его отмены директивой {$F-}, а действие директив far и near распространяется только на ту подпрограмму, в заголовке которой они использованы. Таким образом, ключ (директива) предписывает компилятору вести поиск нужных подпрограмм в разных сегментах памяти, что замедляет работу компилятора.

Если требуется использовать в качестве фактического параметра процедурного типа стандартную процедуру или функцию, то стандартную подпрограмму следует превратить в подпрограмму пользователя с помощью оболочки:

{$F+}

function MySin(x : real) : real;

begin MySin := sin(x) end;.

Директивы inline и interrupt предназначены для создания подпрограмм, написанных в машинных кодах, и процедур, обрабатывающих прерывания, соответственно.

Пример 4. С помощью подпрограммы с параметром процедурного типа ввести и вывести на экран матрицы 5х5 и 7х7.

program Proc_Tip;

const

n = 10;

type

tip = array[1..n, 1..n] of byte; {Тип-матрица}

proc = procedure(var m : tip; r : byte); {Процедурный тип}

var matrix : tip;

procedure Obrabotka(p : proc; var mat : tip; k : byte);

begin {Основная подпрограмма}

p(mat, k)

end;

{$F+} {Объекты процедурного типа}

procedure Vvod(var mat : tip; k : byte);

var

i, j : byte;

begin

randomize;

for i := 1 to k do

for j :=1 to k do

mat[i, j] := random(20*k)

end;

procedure Vyvod(var mat : tip; k : byte);

var

i, j : byte;

begin

writeln('Была введена матрица:');

for i := 1 to k do begin

for j := 1 to k do write(mat[i, j] : 4);

writeln end

end;

{$F-} {Отмена действия ключа дальней компиляции}

begin

Obrabotka(Vvod, matrix, 5);

Obrabotka(Vyvod, matrix, 5);

Obrabotka(Vvod, matrix, 7);

Obrabotka(Vyvod, matrix, 7);

end.

В приведенном примере в качестве объектов процедурного типа выступают две процедуры – ввода и вывода квадратной матрицы задаваемого параметром k размера. По этой причине они имеют одинаковый набор формальных параметров, хотя для вывода матрицы вовсе не требуется параметр-переменная.

Пример 5. Вычислить для заданного значения x значения двух полиномов: f1(x) = 1,2x4 + 4,5x3 – 1,67x + 2,3 и f2(x) = 5,2x4 + 6,3x3 – 7,8x2 + 3,1.

program Polinomy;

type

tip = array[1..5] of real;

const { Задаем два вектоpа коэффициентов для двух полиномов,}

v1 : tip = (2.3, -1.67, 0, 4.5, 1.2); {начиная с младших степеней}

v2 : tip = (3.1, 0, -7.8, 6.3, 5.2);

type

fun = function(m : tip; x : real) : real; {Процедурный тип}

function Sum(ff : fun; vv : tip; arg : real) : real; {Основная подпрограмма}

begin Sum := ff(vv, arg) end;

{ Описываем два полинома }

function f1(v : tip; y : real) : real; far;

begin

f1 := v[1] + v[2]*y + v[3]*y*y + v[4]*y*y*y + v[5]*y*y*y*y

end;

function f2(u : tip; z : real) : real; far

begin

f2 := u[1] + u[2]*z + u[3]*z*z + u[4]*z*z*z + u[5]*z*z*z*z

end;

begin

writeln('Значение пеpвого полинома = ', Sum(f1, v1, 2.1) : 8 : 4);

writeln('Значение втоpого полинома = ', Sum(f2, v2, 1.7) : 8 : 4);

writeln('Нажмите ENTER'); readln

end.