Типы передач параметров в подпрограммы
Автор:
WEC (бывший волшебник)
Оригинал: http://www.noil.pri.ee
Под подпрограммами в этой статье я буду понимать функции и процедуры в Делфи.
Правильный выбор типа передачи параметра в подпрограммы в некоторых случаях может значительно оптимизировать код, экономить память и процессорное время! Особенно если происходит передача больших объемов информации.
Как известно, процедуры в Делфи объявляются следующим образом:
Procedure <Имя процедуры>(<Имя параметра>:<Тип параметра>;<и т.д.>);
А функции так:
Function <Имя функции>(<Имя параметра>:<Тип параметра>;<и т.д.>): <тип возвращаемого значения>;
Подпрограммы могут иметь одинаковое имя, если после объявления подобных подпрограмм, но с разными параметрами(или типами параметров!), использовать операнд overload
Например:
procedure Proc1(X,Y: Integer); overload;
и
procedure Proc1(X,Y: String); overload;
При вызове Proc1('бла-бла','123'); вызовется вторая процедура, а при вызове Proc1(75,123); вызовется первая!
***************************************************
1) Тип передачи параметра "по значению":
Объявление:
procedure Stop(I,J: Integer; B: Boolean);
А вызов такой процедуры может выглядеть следующим образом:
Stop(X,2,True);
или
Stop(X,2,Bool); (где Bool переменная типа Boolean)
Особенности данного типа передачи параметров:
Переменные I,J,B являются временными, то есть существуют только тогда, когда работает процедура Stop(для них выделяется "временная память"). Как только процедура закончит своё выполнение, эти переменные будут автоматически уничтожены. В эти переменные просто-напросто копируется значение из X,2,True. То есть I в процедуре Stop будет равно значению X, J равно двум, а B = True. Притом, когда в процедуре Stop будет происходить изменение значений переменных I,J,B, то это никак не повлияет на переменные, с которых копировалось первоначальное значение(в нашем примере это переменная X)!
***************************************************
2) Тип передачи параметра "по значению, но со значением по умолчанию":
Объявление:
procedure Stop1(I: Integer = 24; J: Integer = 3; B: Boolean = False);
procedure Stop2(I: Integer; J: Integer = 3; B: Boolean = False);
procedure Stop3(I,J: Integer; B: Boolean = False);
Пример вызова подпрограмм:
Подпрограмму Stop1 можно вызывать, передавая параметры или не передавая их, тогда значения переменных будут иметь значения по умолчанию, указанные после знака равно. Или можно передавать часть параметров(остальные будут равны умолчанию), но тогда надо учитывать, что не переданные параметры должны быть всегда справа!
Например:
Stop1();
I равно 24, J равно 3, B равно Fasle.
Stop1(4);
I равно 4, J равно 3, B равно Fasle.
Stop1(4,1);
I равно 4, J равно 1, B равно Fasle.
Stop1(4,1,True);
I равно 4, J равно 1, B равно True.
Пример неправильного вызова:
Stop1(4,,True); - Из-за этого будет ошибка, так как все "не переданные" параметры должны быть при вызове всегда только справа!
У процедур Stop2 и Stop3, первые параметры, не заданные по умолчанию, при вызове должны быть обязательно переданы в отличие от Stop1. Например, так:
Stop2(5);
I равно 5, J равно 3, B равно False.
Stop3(5,7);
I равно 5, J равно 7, B равно False.
Особенности данного типа передачи параметров:
Данный тип передачи параметров позволяет не передавать параметры, когда это требуется. Но нельзя забывать, что и при объявлении подобных подпрограмм указывать умолчание нужно только справа, как и при вызове: правые параметры можно не передавать!
***************************************************
3) Тип передачи параметра "как константа":
Объявление:
procedure Stop(const I,J: Integer; const B: Boolean);
Пример вызова подпрограммы:
Stop(3,X,Bool);
Особенности данного типа передачи параметров:
Как и при первом типе передачи параметра. Но в теле подпрограммы невозможно изменение I,J,B, так как они константы!
Это позволяет сделать код более оптимальным и эффективным.
***************************************************
4) Тип передачи параметра "по указателю(по ссылке)":
Объявление:
procedure Stop(var I,J: Integer; var B: Boolean);
Пример вызова подпрограммы:
Stop(X,Y,Bool);
Особенности данного типа передачи параметров:
В отличие от первого типа передачи, копирование значений не происходит, а I,J,B являются указателями на переменные X,Y,Bool.
Таким образом, при изменении значения у I меняется значение у X, при изменении значения у J меняется значение у Y, при изменении значения у B меняется значение у Bool. Тоесть работа в подпрограмме идёт с внешними переменными по отношению к этой подпрограмме. Таким образом, можно добиться экономии памяти и процессорного времени, особенно если вы в качестве параметра передаёте большое количество данных.
***************************************************
В большинстве случаев различные типы передач параметров можно комбинировать.
С последними двумя типами передач параметров, возможно, не указывать тип переменной при объявлении подпрограммы. То есть переменная будет являться нетипизированной.
Например:
procedure Stop(var I);
Но при объявлении нетипизированых параметров в самой такой подпрограмме надо обязательно пользоваться операцией приведения типа, например:
Integer(I):= 10+50;
или
String(I):= 'бла-бла-бла';
С уважением, WEC (бывший волшебник)