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

Проблема совместимости

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

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

Механизм процедурных типов предоставляет программисту весьма широкие и удобные возможности при разработке программ. Корректная работа требует соблюдения следующих правил.

  • Подпрограмма, присваиваемая процедурной переменной, должна быть оттранслирована в режиме «дальнего типа вызовов». Для достижения эффекта необходимо перед подпрограммой или группой подпрограмм расположить директиву компилятора $F со знаком +, а в конце группы со знаком -.

Пример

{$F+}

function Add (a,b: real):real;

begin

Add:=a+b

end;

function Sub (a,b: real):real;

begin

Sub:=a-b

end;

{$F-}

Если необходимо распространить действие этой директивы на всю программу, то достаточно одну {$F+} поместить в самом начале текста.

Эквивалентом директивы компилятора {$F+} является служебное слово far, которое должно быть записано перед блоком подпрограммы. (другой - «близкий» тип вызова задаётся служебным словом near).

function add (a,b: real):real; far;

begin

Add:=a+b

end;

  • Подпрограмма, присваиваемая процедурной переменной, не должна быть стандартной процедурой или функцией. Это ограничение при необходимости можно легко обойти, заключив вызов стандартной подпрограммы в «оболочку», после чего её можно использовать в качестве присваивания.

Пример

var

Func: function (s: string): byte;

….......

function Mylength (s: string): byte; far;

begin

Mylength:=length(s)

end;

………

Func:= Mylength;

  • Важное ограничение – обсуждаемые подпрограммы не могут быть вложенными в другие подпрограммы.

  • Подпрограммы, присваиваемые процедурным переменным, не могут быть подпрограммами специального вида, содержащими спецификации interrupt и конструкцию inline.

Можно описывать процедуры и функции, параметрами которых являются процедурные переменные.

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

Пример

program Tables;

type

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

function Add(a, b: integer):integer; far;

begin

Add:=a+b;

end;

function Mult(a, b: integer): integer; far;

begin

Mult:=a+b;

end;

procedure MakeTable(w, h:integer; operation: func);

var

i, j:integer;

begin

write(‘ ‘);

for i:=1 to w do write(‘_ _ _ _ _ ‘);

writeln;

for i:=1 to h do begin

write(i: 5,’ | ‘);

for j:=1 to w do

write(operation(j, i): 5);

writeln;

end;

writeln; end;

begin

Make_table(10,10, Add);

Make_table(10,10, Mult);

end.

Два вызова процедуры MakeTable, которая строит таблицы, используя для вычисления в первом случае функцию Add, во втором – Mult.

Переменные процедурных типов можно передавать в качестве параметров подпрограммы.

Функции, возвращающие значения процедурных типов, не допускаются.

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

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

Пример

type

IntFunc= function: integer;

var

f: IntFunc;

n: integer;

function ReadInt: integer; far;

var

i: integer;

begin

read(i);

ReadInt:=i;

end;

begin

f:= ReadInt; {присваивание значения процедуры}

n:= Readint; { присваивание результата функции}

end.

Первый оператор в основной программе присваивает значение процедуры Readint (её адрес) процедурной переменной F, второй вызывает функцию Readint и присваивает полученное значение переменной n. Полученные значения процедуры или вызов функции различаются по типу присваиваемой переменной(f или n).

Дополнение Директивы подпрограмм дают информацию о размещении подпрограмм.

  1. FORWARD- директива заголовка подпрограммы описанной дальше по тексту.

  2. FAR, NEAR- директивы формирования «дальнего» адреса и «ближнего» адреса.

  3. EXTERNAL- директива внешней подпрограммы.

  4. ASSEMBLER- директива подпрограммы, написанной на ассемблере.

  5. INLINE- директива, позволяющая включить в программу часть, написанную на ассемблере.

  6. INTERRUPT – директива процедуры обработки прерываний.

(См. пункт 10.5.

Епанишников А.М., Епанешников В.А. Программирование в среде Turbo -Pascal 7.0. М.: Диалог- МИФИ. 2001. -288 с.)