Список параметров, задаваемый в заголовке процедуры и функции, обеспечивает связь подпрограммы с вызывающей программой. Через него в подпрограмму передаются исходные данные и возвращается результат. При этом предусмотрены два принципиально отличающихся механизма передачи параметров – по значению и по ссылке. Синтаксически эти два способа отличаются употреблением слова var перед соответствующей переменной в заголовке подпрограммы. Если это слово имеется, переменная передаётся по ссылке, если нет – по значению.
При вызове по значению в подпрограмме создаются переменные, в соответствии с объявлениями в заголовке подпрограммы. Эти переменные существуют только на время выполнения подпрограммы. В вызывающей программе в качестве аргумента (фактического параметра) может использоваться не только переменная, но и выражение. В начале выполнения подпрограммы значение этой переменной или выражения присваивается внутренней временной переменной подпрограммы. Когда подпрограмма завершается , используемые подпрограммой переменные не сохраняют своего значения, поэтому передачу данных по значению можно использовать только для передачи данных в подпрограмму, но не для получения от неё результатов.
При вызове по ссылке в подпрограмме память под передаваемые переменные не отводится. Основная программа передаёт в подпрограмму не значение переменной, а ссылку на место в памяти основной программы, где расположена эта переменная. Подпрограмма, производя некоторые действия с этой переменной, в действительности производит действия с переменной основной программы, поэтому после выполнения процедуры изменения, совершенные с переменными основной программы, сохраняются. Этот механизм используется для получения от подпрограммы результатов её выполнения. Понятно, что при вызове подпрограммы с передачей данных по ссылке невозможно использовать в качестве аргументов выражения или константы, так как они не имеют адреса для передачи.
Лекция №7
Рассмотрим несколько примеров подпрограмм, в которых используются обращения по значению и по ссылке.
Пример 2.
program exzempl2;
var a,b:char;
procedure p(x:char;var y:char);
begin
a:='+';
y:=x
end;
procedure q(var x,y:char);
begin
a:='+';
y:=x
end;
{ *********** main program *********** }
begin
a:='*'; p(a,b);
writeln(a,' ',b);
a:='*'; q(a,b);
writeln(a,' ',b);
end.
В первом случае будет напечатано
При первом обращении к процедуре p создается локальная переменная x, куда закачивается значение переменной a, представляющее в этот момент символ ‘*’. Изменение же параметра y приводит к изменению по адресу совпадающим с адресом переменной b. Изменение глобальной переменной а с символа * на символ + происходит в теле подпрограммы уже после того как в локальную переменную х было записано значение *.
Во втором случае будет напечатано
При втором обращении к процедуре q для х передаётся адрес переменной а, для у передается адрес переменной b.
Поэтому изменение в теле подпрограммы значения а на символ + приводит к тому, что у, а следовательно и b изменяется на значение +.