Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на языке Delphi_1.doc
Скачиваний:
43
Добавлен:
28.03.2015
Размер:
710.14 Кб
Скачать
      1. 2.7.3. Вызов процедур и функций

Параметры, которые передаются в подпрограмму при ее вызове, называются фактическими.

Вызов процедуры для выполнения осуществляется по ее имени, за которым в круглых скобках следует список фактических параметров, т.е. передаваемых в процедуру данных:

<имя процедуры> ( <список фактических параметров> );

Рассмотрим пример.

Var

A, G: Double;

procedure Average(const X, Y: Double; out M, P: Double);

begin

M := (X + Y) / 2;

P := Sqrt(X * Y);

end;

procedure TForm1.Button1Click(Sender:Tobject);

begin

Average(10, 20, A, G);

ShowMessage('Среднее арифметическое = ', FloatToStr(A));

ShowMessage('Среднее геометрическое = ', FloatToStr(G));

End; end.

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

1. Выражения, используемые для передачи в типизированные параметры-константы и в параметры-значения должны быть совместимыми по присваиванию с соответствующими формальными параметрами.

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

3. На место параметров, передаваемых по ссылке можно подставлять только переменные, нельзя – числа и константы.

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

5. Если вызывается подпрограмма с параметрами по умолчанию, то все фактические параметры по умолчанию, идущие перед тем параметром, который необходимо передать значение, отличное от умолчания, должны быть заполнены. Например, SomeFunction(,,X) – некорректен.

      1. 2.7.4. Перегрузка процедур и функций

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

procedure IncrementInteger(var Value: Integer);

procedure IncrementReal(var Value: Real);

В языке Delphi существует возможность дать двум и более процедурам (функциям) одинаковые идентификаторы при условии, что все такие процедуры (функции) отличаются списком параметров (количеством параметров или типом параметров). Такая возможность называется перегрузкой. Для указания того, что процедура (функция) перегружена, служит стандартная директива overload. С ее помощью вышеприведенный пример можно переписать следующим образом:

procedure Increment(var Value: Integer); overload; // процедура 1

procedure Increment(var Value: Real); overload; // процедура 2

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

Var

X: Integer;

Y: Real;

begin

X:=1;

Y:=2.0;

Increment(X); // Вызывается процедура 1

Increment(Y); // Вызывается процедура 2

end.

Особенности перегрузки:

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

procedure Print(X: Shortint); overload; // процедура 1

procedure Print(X: Longint); overload; // процедура 2

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

Print(5); // Вызывается процедура 1

Print(150); // Вызывается процедура 2

Print(-500); // Вызывается процедура 2

Print(-1); // Вызывается процедура 1

Очевидно, что одно и то же число может интерпретироваться и как Longint, и как Shortint (например, числа 5 и –1). Логика компилятора в таких случаях такова: если значение фактического параметра попадает в диапазон значений нескольких типов, по которым происходит перегрузка, то компилятор выбирает процедуру (функцию), у которой тип параметра имеет меньший диапазон значений. Например, вызов Print(5) будет означать вызов того варианта процедуры, который имеет тип параметра Shortint. А вот вызов Print(150) будет означать вызов того варианта процедуры, который имеет тип параметра Longint, т.к. число 150 не вмещается в диапазон значений типа данных Shortint.

2. Поскольку в нынешней версии среды Delphi обощенный тип данных Integer совпадает с фундаментальным типом данных Longint, следующий вариант перегрузки является ошибочным:

procedure Print(X: Integer); overload;

procedure Print(X: Longint); overload; // Ошибка!

3. Такая же ошибка возникает при использовании пользовательских типов данных, определенных через общий базовый тип.

Type

TMyInteger = Integer;

procedure Print(X: Integer); overload;

procedure Print(X: TMyInteger); overload; // Ошибка!

Что делать в тех случаях, когда такая перегрузка просто необходима? Для этого пользовательский тип данных необходимо создавать с использованием ключевого слова type:

Type

TMyInteger = type Integer;

procedure Print(X: Integer); overload;

procedure Print(X: TMyInteger); overload; // Правильно

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

procedure Increment(var Value: Real; Delta: Real = 1.0); overload;//процедура 1

procedure Increment(var Value: Real); overload; //процедура 2

Вызов процедуры Increment с одним параметром вызовет неоднозначность (необходимо избегать одинаковых сигнатур подпрограмм до этих параметров):

Var

X: Real;

begin

Increment(X, 10); // Вызывается процедура 1

Increment(X); // Ошибка! Неоднозначность

end.

5. Запрещается также перегружать функции, которые отличаются лишь типом возвращаемого значения.

function SquareRoot(X: Integer): Single; overload;

function SquareRoot(X: Integer): Double; overload; // Ошибка!

6. Запрещается также перегружать подпрограммы, которые отличаются типом: в одном случае функция, в другом - процедура.