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

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

function Calc(X,Y: Integer): Integer;

Эта функция может быть определена как тип для переменной F:

var F: function(X,Y: Integer): Integer;

и связана с этой переменной оператором присваивания:

F := Calc;

Точно так же можно определить любой другой новый процедурный тип и переменную:

Type {объявление процедурных типов}

TIntegerFunction = function: Integer;

TProcedure = procedure;

TStrProc = procedure(const S: string);

TMathFunc = function(X: Double): Double;

Var {объявление процедурных переменных}

F: TIntegerFunction; {F функция без параметров, возвращающая целое}

Proc: TProcedure; {Proc – процедура без параметров}

SP: TStrProc;

M: TMathFunc;

При использовании операторов над процедурными типами и процедурами или функциями необходимо различать связывание процедурной переменной и обращение к процедуре или функции. Так в нижеследующем примере объявляются переменная F типа функции, а переменная I – простого целочисленного типа, затем следует текст процедуры SomeFunction:

F: function(X: Integer): Integer;

I: Integer;

 

function SomeFunction(X: Integer): Integer;

...

В операторной части первый оператор связывает F с конкретной функцией, не производя над ней никаких действий:

F := SomeFunction;

напротив, оператор

I := F(4);

вызывает эту функцию (запускает ее алгоритм) и после обработки возвращает результат вычислений переменной I.

 

15.6. Формальные и фактические параметры

В Object Pascal есть понятия формального и фактического параметров. Формальным называется параметр, который содержится в заголовке описания подпрограммы, а фактическим – параметр в обращении к подпрограмме. Так, в вышеприведенном примере параметр X является формальным, а значение 4 – фактическим.

При вызове подпрограмм необходимо иметь в виду следующее:

фактические значения или константы должны быть совместимы по типу с объявленными формальными параметрами;

фактические var или out-параметры должны быть идентичны по типу объявленным формальным параметрам, исключением являются только нетипизированные параметры;

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

Приведем еще один пример, демонстрирующий способы обращения к подпрограммам.

Const

IntCount = 1200;

Type

TFunc12 = Function(c1, c2: Integer): Integer;

Function Func12_1(k1, k2: Integer): Integer;

Begin

Result:= k1 + k2;

End;

Function Func12_2(g1, g2: Integer): Integer;

Begin

Result:= g1 - g2;

End;

Procedure AnyPro(u1: Real; Var u2: Real; Var u3; Const u4: Integer; F: tFunc12);

Begin

u2:= u1 + u4 + F(u4, Round(u4 * 3.14));

u3:= u1 - u4 - F(u4, Round(u4 * 3.14));

End;

Var

k: Integer;

v1, v2: Real;

ss: String;

{примеры обращения к процедуре AnyPro:}

AnyPro(v1, v2, v1, v2, Func12_1);

AnyPro(v1, v2, ss, v1, Func12_2);

AnyPro(k, v1, ss, v2, Func12_1);

AnyPro(k + 8, v2, ss, IntCount, Func12_1);

AnyPro(8, v2, ss, v1+6.7, Func12_2);

Параметры u1, u2, u3, u4, F в заголовке процедуры AnyPro, являются формальными параметрами: u1 – константа типа Real; u2 – переменная типа Real; u3 – переменная без типа; u4 – константа типа Integer; F – параметр-функция типа TFunc12, который объявлен выше в секции Type.

Параметры, заключенные в скобки в примерах обращения к процедуре AnyPro, являются фактическими параметрами. Такие параметры могут быть значениями (8), константами (IntCount), переменными (v1), выражениями (k + 8), именами процедур или функций (Func12_1) и др.

 

15.7. Область действия имен

В подпрограммах часть параметров может быть объявлена прямо в заголовке или ее теле. Такие параметры действуют только внутри этой подпрограммы и поэтому называются локальными параметрами. В то же время в подпрограмме можно использовать параметры, которые описаны за пределами подпрограммы. Такие параметры называются глобальными параметрами.

Глобальные параметры могут быть описаны в том же модуле, который содержит использующую их подпрограмму, или в другом модуле, на который имеется ссылка в списке uses. Если два параметра имеют одинаковое имя и один из них описан внутри подпрограммы, а другой – вне ее, то действует тот параметр, который описан в подпрограмме. Аналогично определяется область доступности параметров описанных в разных модулях. Таким образом, при описании имен действует следующий принцип: более позднее объявление отменяет облаcть действия ранее описанных имен. Внутри одной подпрограммы нельзя объявлять двух и более одинаковых имен.

Поясним область действия имен на примере следующего модуля

Unit Mod4;

interface

uses Mod1, Mod2, Mod3;

….

Type

Vr = Integer; {допустимо}

Var

Vr: Real; {недопустимо}

implementation

Var Vr: Char; {недопустимо}

procedure Pro1; {не содержит внутреннего объявления имени Vr}

procedure Pro2; { содержит внутреннее объявление имени Vr}

Var

Vr: String; {допустимо}

Vr: Real; {недопустимо}

В приведенном тексте модуля Mod4 содержится несколько описаний имени Vr, часть которых допустима, другая часть ошибочна. Недопустимо описание этого имени:

в var-секции в разделе interface, так как оно уже использовано в этом же разделе выше – в секции type;

в var-переменной в разделе implementation, так как оно уже использовано в этом же модуле в разделе interface;

как переменной типа Real в теле процедуры Pro2, т. к. оно уже использовано в этой же процедуре при описании String-переменной.

Более позднее объявление отменяет действие ранее описанного имени. Так, внутри процедуры Pro2 имя Vr представляет переменную типа String, а внутри процедуры Pro1 имя Vr действует как глобальный тип Integer, объявленный выше – в секции type.

Если бы это имя вообще не было описано в модуле Mod4, но было бы объявлено в одном или нескольких модулях, указанных в ссылочном списке uses, то оно могло бы быть использовано как глобальный параметр внутри этого модуля (Mod4). При этом действовало бы то имя, которое объявлено в разделе interface самого последнего содержащего его модуля списка uses. Например, если имеется описание имени Vr в модулях Mod1 и Mod2, то действовало бы описание из Mod2. Если в списке uses поменять Mod1 и Mod2 местами, то будет действовать описание, которое выполнено для этого имени в модуле Mod1.

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

Function Deccy(x: Integer) : Integer;

Begin

d:= d - x;

Deccy:= Sqr(x);

End;

d:= 3; a:= Deccy(3) * Deccy(d); {a= 0, d= 0}

d:= 3; a:= Deccy(d) * Deccy(3); {a= 81, d= -3}

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

 


Информация о работе «Object Pascal»
Раздел: Информатика, программирование
Количество знаков с пробелами: 162712
Количество таблиц: 21
Количество изображений: 0

Похожие работы

Скачать
49877
5
0

... в среде Delphi). Задачи использовались как с данного сайта, так и из других источников – книг и семинарских занятиях по информатике в МГОУ. Курс завершается разработкой игры. Программное обеспечение: свободно распространяемая версия объектно-ориентированной среды программирования Delphi. Методы обучения: метод проектов, лекции, проблемный метод, частично-поисковый метод. Контроль знаний и умений ...

Скачать
17314
1
5

... // ... if(condition1) { j = 4; goto label1; } // ... for(j = 0; j < 10; j++) { // ... label1: // ... if(condition2) { i = 6; goto label2; } } // ... label2: // ... } 2.2       Разработка программы В среде программирования Borland Delphi создадим новое приложение (пункт меню File New Application). ...

Скачать
27554
2
0

... так называемые указатели. Указатель - это переменная, которая в качестве своего значения содержит адрес байта памяти. С помощью указателей можно размещать в динамической памяти любой из известных в Object Pascal типов данных. Лишь некоторые из них (Byte, Char, ShortInt, Boolean) занимают во внутреннем представлении один байт, остальные - несколько смежных. Поэтому на самом деле указатель адресует ...

Скачать
62207
3
0

... групп нулей и единиц. Каждая группа отделяется друг от друга одним или несколькими пробелами. Найти и вывести на экран группы с четным количеством символов. Лабораторная работа №6 Программирование АЛГОРИТМОВ с использованием записей Цель лабораторной работы: создать приложение, в котором используются данные типа запись. 6.1.Пример создания приложения Задание: создать Windows-приложение для ...

0 комментариев


Наверх