Показаны сообщения с ярлыком Процедуры. Показать все сообщения
Показаны сообщения с ярлыком Процедуры. Показать все сообщения

вторник, 3 декабря 2013 г.

Необязательный параметр в процедуре (Вариант 3. Значение по умолчанию)

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

procedure MyProc(a : Byte; b : Byte = 23);

Может быть вызвана 2-мя способами:

MyProc(15, 16);
MyProc(45); // По умолчанию b будет равно 23

Необязательный параметр в процедуре (Вариант 2. Использование Overload)

Директива Overload позволяет Вам иметь различные версии одинаково названной функции или процедуры с различными параметрами. Это полезно, когда есть множество путей, которыми код может захотеть использовать подпрограмму. Например, если подпрограмма - конструктор класса, Вы можете хотеть иметь одну версию Create, которая устанавливает значения по умолчанию, и другую, которая берет эти значения как параметры. 

Вы должны закодировать директиву Overload перед любыми другими директивами. 

При запросе перезагруженной (overloaded) подпрограммы, Delphi выбирает соответствующую версию, основанную сначала на номере параметров, затем на типах параметра. Если он не может принять решение, он выдаёт исключение. 

Когда количество параметров такое же, он всегда сначала пробует удовлетворить самые простые/наименьшие типы данных - например, вышеупомянутое значение 23 удовлетворил бы параметр Byte, чемInteger параметр. 

Пример использования

function Summ(A, B: integer): integer; overload;       // Версия 1 функции Summ
begin
  result:= A+B;
end;

function Summ(A,B,C: Integer): integer; overload;  // Версия 2 функции Summ
begin
 result:=A+B+C;
end;

Function ShowSumm;
begin
  ShowMessage(Summ(5,10));      // Используется версия 1 функции Summ
  ShowMessage(Summ(3,7,12));   // используется версия 2 функции Summ
end;

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

function Summ(A, B: integer): integer; overload;       // Измененная версия 1 функции Summ
begin
  result:= Summ(A,B, 0);
end;

В данном случае, мы вызываем версию с 3-мя параметрами, передавая два числа и 0, который не влияет на сумму). Но это частный случай.

Необязательный параметр в процедуре (Вариант 1. Открытые массивы)

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


function AddEmUp( A: array of integer ): integer;


В открытом массиве можно передавать переменные, константы или выражения из констант. Ниже приведен пример, который демонстрирует вызов функции AddEmUp с передачей ей нескольких различных элементов. 


const
  j = 23;
var
  i, Rez: integer;
begin
   i := 8;
   Rez := AddEmUp( [i, 20, j, 43] );
end; 


Для получения информации о фактически передаваемом массиве параметров в функции или процедуре могут использоваться функции High, Low и SizeOf. Для иллюстрации их использования ниже приведен текст функции AddEmUp, которая возвращает сумму всех переданных ей элементов массива A. 


function AddEmUp( A: array of integer ): integer;
var
   i: integer;
begin
   Result := 0;
   for i := Low(A) to High(A) do
       Inc( Result, A[i] );
end; 


Object Pascal также поддерживает тип array of const, который позволяет передавать в одном массиве данные различных типов. Синтаксис объявления функций или процедур, использующих такой массив для получения параметров, следующий: 

procedure WhatHaveIGot( A: array of const ); 


Вызвать объявленную выше функцию можно, например, с помощью такого оператора:


procedure WhatHaveIGot( ['Text', 10, 5.5, @WhatHaveIGot, 3.14, true, 'c'] ); 


При передаче функции или процедуре массива констант все передаваемые параметры компилятор неявно конвертирует в тип TVarRec. Тип данных TVarRec объявлен в модуле System следующим образом: 


PVarRec = ^TVarRec;
TVarRec = record case
  Byte of vtInteger: (VInteger: Integer; VType: Byte);
        vtBoolean: (VBoolean: Boolean);
        vtChar: (VChar: Char);
        vtExtended: (VExtended: PExtended);
        vtString: (VString: PShortString);
        vtPointer: (VPointer: Pointer);
        vtPChar: (VPChar: PChar);
        vtObject: (VObject: TObject);
        vtClass: (VClass: TClass);
        vtWideChar: (VWideChar: WideChar);
        vtPWideChar: (VPWideChar: PWideChar);
        vtAnsiString: (VAnsiString: Pointer);
        vtCurrency: (VCurrency: PCurrency);
        vtVariant: (VVariant: PVariant);
        vtInterface: (VInterface: Pointer);
        vtWideString: (VWideString: Pointer);
        vtInt64: (VInt64: PInt64);
end;


Поле VType определяет тип содержащихся в данном экземпляре записи TVarRec данных и может принимать одно из ниже приведенных значений.

const
  vtInteger = 0;
  vtBoolean = 1;
  vtChar = 2;
  vtExtended = 3;
  vtString = 4;
  vtPointer = 5;
  vtPChar = 6;
  vtObject = 7;
  vtClass = 8;
  vtWideChar = 9;
  vtPWideChar = 10;
  vtAnsiString = 11;
  vtCurrency = 12;
  vtVariant = 13;
  vtInterface = 14;
  vtWideString = 15;
  vtInt64 = 16; 


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


procedure WhatHaveIGot( A: array of const );
var
   i: integer; TypeStr: string;
begin
   for i := Low(A) to High(A) do begin
     case A[i].VType of
          vtInteger : TypeStr := 'Integer';
          vtBoolean : TypeStr := 'Boolean';
          vtChar : TypeStr := 'Char';
          vtExtended : TypeStr := 'Extended';
          vtString : TypeStr := 'String';
          vtPointer : TypeStr := 'Pointer';
          vtPChar : TypeStr := 'PChar';
          vtObject : TypeStr := 'Object';
          vtClass : TypeStr := 'Class';
          vtWideChar : TypeStr := 'WideChar';
          vtPWideChar : TypeStr := 'PWideChar';
          vtAnsiString : TypeStr := 'AnsiString';
          vtCurrency : TypeStr := 'Currency';
          vtVariant : TypeStr := 'Variant';
          vtInterface : TypeStr := 'Interface';
          vtWideString : TypeStr := 'WideString';
          vtInt64 : TypeStr := 'Int64';
    end;
   ShowMessage( Format( 'Array item %d is a %s', [i, TypeStr] ) );
  end;
end;

Найдено на http://programmersforum.ru/