Применение процедурного типа не ограничивается одним лишь описанием параметров-процедур или функций. Раз есть такой тип, то могут быть и переменные такого типа.

<p>6.9.5. Переменные-процедуры и функции</p>

Рассмотрим программу на рис. 6.13. В ней вводятся две переменные-процедуры P1 и P2 и демонстрируются возможные действия с ними.

| TYPE DemoProcType = procedure ( А,В : Word );

| VAR

| Р1, Р2 : DemoProcType; { переменные-процедуры} P : Pointer; { просто указатель }

| { Значения переменных-процедур : }

| {$F+}

| PROCEDURE Demo1( X,Y : Word );

| BEGIN WriteLn( 'x+y=', x+y ) END;

| PROCEDURE Demo2( X,Y : Word );

| BEGIN WriteLn( 'x-y=', x-y ) END;

| {$F-}

| BEGIN { основной блок программы }

| P1 := Demo1; { присваивание значений переменным }

| P2 := Demo2;

| P1( 1, 1 ); { то же самое, что и вызов Demo1(1,1) }

| P2( 2, 2 ); { то же самое, что и вызов Demo2(2,2) }

| { Ниже в указатель Р запишется адрес процедуры Р1: }

| DemoProcType( P ) := P1;

| DemoProcType(P)( 1, 1 ); { то же, что и вызов Р1(1,1) }

| { Так значение указателя Р передается переменной : }

| @P2 := Р;

| Р2( 2,2 ); { процедура Р2 в итоге стала равна Р1 }

| END.

Рис. 6.13

Процедурные переменные по формату совместимы с переменными типа Pointer и после приведения типов могут обмениваться с ними значениями. Для того чтобы переменная-процедура понималась как указатель на адрес подпрограммы в ОЗУ, она должна предваряться оператором @. Советуем не злоупотреблять операциями обмена значений таких переменных, тем более с приведениями типов. Програм-

- 117 -

мы с подобными приемами очень трудно отлаживать, и они имеют тенденцию «зависать» при малейшей ошибке.

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

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

TYPE

ProcType = ПроцедурныйИлиФункциональныйТип;

DemoRecType = RECORD

X,Y : Word;

Op : ProcType;

END;

VAR

Rec1,Rec2 : DemoRecType;

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

Обращаем внимание на еще одну особенность работы с процедурными переменными. Если надо убедиться, что процедуры или функции, понимаемые под двумя переменными, одинаковы, то операция сравнения запишется (для переменных Rec1.Op и Rec2.Op) как

IF @Rec1.Op = @Rec2.Op then ... ;

Если убрать оператор @, то при значениях полей Op, соответствующих процедурам, это будет просто синтаксически неверно, а при значениях Op, соответствующих функциям без параметров, будут сопоставляться не сами поля Op, а результаты вызовов функций.

<p>6.9.6. Специальные приемы программирования</p>

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

- 118 -

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

| TYPE

| Vector100Type = Array[1..100] of Real; {вектор }

| MatrixType = Array[1..10,1..10] of Real; { матрица }

| Matrix2Type = Array[1..50,1..2 ] of Real; { матрица }

| VAR

| V : Vector100Туре: { область памяти на 100 элементов }

| PROCEDURE P1;

| VAR M : MatrixType absolute V; { M совмещается с V }

| BEGIN

Перейти на страницу:

Поиск

Похожие книги