Читайте также: |
|
Тип в объявлении формального параметра пока будем считать обязательным и задавать только именем ранее объявленного или стандартного типа (другие возможности будут рассмотрены позже).
Прежде чем перейти к пояснению правил объявления формальных параметров, введем в рассмотрение два термина: входной параметр и выходной параметр. Параметр считается входным, если он представляет исходные данные для счёта по алгоритму подпрограммы (в рассмотренном примере оба параметра являются входными). Параметр считается выходным, если он представляет результаты счёта по подпрограмме. Допускается, что один и тот же параметр может одновременно представлять и исходные данные и результат, то есть быть одновременно и входным, и выходным.
В языке Object Pascal рассмотренное функциональное деление параметров (на входные, выходные, входные-выходные) дополнено механизмами реализации их функций, отраженными в правилах объявления формальных параметров. Сначала рассмотрим два вида объявлений параметров: параметры-значения и параметры-переменные.
Параметры-значения всегда являются только входными параметрами. Соответствующими фактическими параметрами могут быть выражения (в частности, константы и переменные). При вызове подпрограммы выражения вычисляются, и полученные значения заносятся (а значения констант и переменных просто копируются) в ячейки памяти, представленные соответствующими формальными параметрами, значения которых внутри подпрограммы можно изменять. Механизм параметров-значений таков, что эти изменения никак не отразится на значениях фактических параметров, то есть после выхода из подпрограммы они останутся неизменными. Таким образом, формальный параметр-значение можно рассматривать как переменную, известную внутри подпрограммы, а механизм таких параметров – как защиту фактических параметров, если они являются переменными, от непреднамеренного изменения.
Объявление параметров-значений даётся просто их именем (списком имен через запятую) и типом (без предшествующих слов var, const, out). В рассмотренной процедуре PutMod5 оба параметра являются параметрами-значениями.
Параметры-переменные являются одновременно и входными, и выходными параметрами. Соответствующими фактическими параметрами могут быть только переменные. Механизм параметров-переменных таков, что изменения, выполняемые в алгоритме подпрограммы над соответствующими формальными параметрами, приводят к изменению значений фактических параметров, и эти изменения сохранятся после выхода из подпрограммы. Достигается это за счет того, что в подпрограмму передаётся не сама переменная, а ссылка на неё, то есть обеспечивается непосредственный доступ из подпрограммы к данным фактического параметра.
Объявление параметров-переменных даётся с предшествующим их имени (списку имен) словом var и типом.
Пример процедуры, умножающей данные в первых n ячейках массива Mas на дробную часть числа R. Все участвующие в обработке данные должны передаваться через параметры.
type tMas=array[1..8] of Real;
.....
//Объявление процедуры
procedure MasMulR(R:Real; N:Integer; var Mas:tMas);
var
i:Integer;
begin
R:=Frac(R);//Получить дробную часть R
for i:=1 to N do
Mas[i]:=Mas[i]*R;
end;//MasMulR – конец текста процедуры
.....
var
X:tMas=(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);
Z:Real=3.4;
.....
begin // РАЗДЕЛ ОПЕРАТОРОВ ПРОГРАММЫ
.....
MasMulR(Z,5,X);//Вызов процедуры
.....
end.
В этом примере параметр Mas является и входным, и выходным, поэтому он объявлен как параметр-переменная (с предшествующим словом var). Параметр R является только входным. Так как он объявлен как параметр-значение, то его значение можно, после того, как оно будет использовано как входное данное, менять внутри подпрограммы, то есть использовать как дополнительную переменную, не опасаясь, что изменим значение соответствующего фактического параметра. При указанных в примере начальных значениях переменных после выполнения процедуры переменная Z сохранит своё значение 3.4, а в массиве будут следующие данные: (0.4, 0.8, 1.2, 1.6, 2.0, 6.0, 7.0, 8.0).
Параметры-значения обладают одним недостатком, который может быть очень существенным, если параметром является структурная переменная, например, массив, занимающая большой объём памяти. В этом случае подпрограмма, получив управление, должна выделить такой же объём памяти, какой занимает фактический параметр, и скопировать в неё данные из фактического параметра. То есть недостаток состоит в том, что нерационально используется память и происходит потеря времени на копирование данных перед началом их обработки по алгоритму подпрограммы. Указанных недостатков лишен другой вид входного параметра, получивший название «параметр-константа».
Параметр-константа, как и параметр-значение, служит для представления только входных данных. При его использовании в подпрограмму передаётся ссылка на фактический параметр (как и для параметра-переменной), но, чтобы исключить его непреднамеренное изменение во время работы программы, уже на этапе компиляции выполняются соответствующие проверки и исполняемая программа не создаётся, если подпрограмма содержит операторы, которые могут изменить данные фактического параметра.
Объявление параметров-констант даётся с предшествующим их имени (списку имен) словом const и типом.
Последний вид параметра следует использовать для параметров, представляющих только результаты работы подпрограммы. По аналогии с параметрами других видов ему подошло бы название параметр-результат, или по предшествующему его имени слову out в объявлении – параметр-выходная переменная. Этот параметр передаётся по ссылке, но компилятор не запрещает его использования в качестве источника исходных данных. За этим должен следить программист, а слово out перед его именем в списке формальных параметров призвано облегчить понимание алгоритма подпрограммы, напоминая, что этот параметр не представляет входных данных.
Пример процедуры, в объявлении которой желательно использовать параметр-константу и параметр-результат. Подпрограмма должна вычислять сумму положительных элементов массива X(100,100) и их количество.
type
tMas=array[1..100,1..100] of Extended;
.....
//Объявление процедуры
procedure SumCol(const X:tMas, out S: Extended; out K:Integer);
var
i,j: Integer;
begin
S:=0;
K:=0;
for i:=1 to 100 do
for j:=1 to 100 do
if X[i,j]>0 then
begin
S:=S+X[i,j];
K:=K+1;
end;
end;
.....
var
Y:tMas; Sum: Extended; Col: Integer;
.....
begin // РАЗДЕЛ ОПЕРАТОРОВ ПРОГРАММЫ
.....
SumCol(Y,Sum,Col);
.....
end.
Взглянув на заголовок подпрограммы, сразу можно сказать, что первый параметр является только входным, а два последних – только выходными. Первый параметр объявлен параметром-константой, а не параметром-значением, чтобы избежать выделения памяти в 100000 байт и копирования в неё данных из фактического параметра - массива Y.
Дата добавления: 2015-07-26; просмотров: 83 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Процедуры | | | Задания 5.1 для самостоятельной проработки |