Lecture 6
End.
Begin
Begin
Begin
End.
Begin
Begin
Begin
End.
Begin
Begin
Begin
End.
Begin
Begin
Begin
Begin
Лекция №7
Вызов по ссылке и по значению
Список параметров, задаваемый в заголовке процедуры и функции, обеспечивает связь подпрограммы с вызывающей программой. Через него в подпрограмму передаются исходные данные и возвращается результат. При этом предусмотрены два принципиально отличающихся механизма передачи параметров – по значению и по ссылке. Синтаксически эти два способа отличаются употреблением слова var перед соответствующей переменной в заголовке подпрограммы. Если это слово имеется, переменная передаётся по ссылке, если нет – по значению.
При вызове по значению в подпрограмме создаются переменные, в соответствии с объявлениями в заголовке подпрограммы. Эти переменные существуют только на время выполнения подпрограммы. В вызывающей программе в качестве аргумента (фактического параметра) может использоваться не только переменная, но и выражение. В начале выполнения подпрограммы значение этой переменной или выражения присваивается внутренней временной переменной подпрограммы. Когда подпрограмма завершается , используемые подпрограммой переменные не сохраняют своего значения, поэтому передачу данных по значению можно использовать только для передачи данных в подпрограмму, но не для получения от неё результатов.
При вызове по ссылке в подпрограмме память под передаваемые переменные не отводится. Основная программа передаёт в подпрограмму не значение переменной, а ссылку на место в памяти основной программы, где расположена эта переменная. Подпрограмма, производя некоторые действия с этой переменной, в действительности производит действия с переменной основной программы, поэтому после выполнения процедуры изменения, совершенные с переменными основной программы, сохраняются. Этот механизм используется для получения от подпрограммы результатов её выполнения. Понятно, что при вызове подпрограммы с передачей данных по ссылке невозможно использовать в качестве аргументов выражения или константы, так как они не имеют адреса для передачи.
Рассмотрим несколько примеров подпрограмм, в которых используются обращения по значению и по ссылке.
Пример 2.
program exzempl2;
var a,b:char;
procedure p(x:char;var y:char);
a:='+';
y:=x
end;
procedure q(var x,y:char);
a:='+';
y:=x
end;
{ *********** main program *********** }
a:='*'; p(a,b);
writeln(a,' ',b);
a:='*'; q(a,b);
writeln(a,' ',b);
end.
В первом случае будет напечатано
При первом обращении к процедуре p создается локальная переменная x, куда закачивается значение переменной a, представляющее в этот момент символ ‘*’. Изменение же параметра y приводит к изменению по адресу совпадающим с адресом переменной b. Изменение глобальной переменной а с символа * на символ + происходит в теле подпрограммы уже после того как в локальную переменную х было записано значение *.
Во втором случае будет напечатано
При втором обращении к процедуре q для х передаётся адрес переменной а, для у передается адрес переменной b.
Поэтому изменение в теле подпрограммы значения а на символ + приводит к тому, что у, а следовательно и b изменяется на значение +.
Пример 3
program exzampl3;
uses crt;
var a,b:integer;
function f(x:integer):integer;
begin f:=x; a:=0 end;
function g(var x:integer):integer;
begin g:=x; x:=0 end;
{ ********* main program ********** }
ClrScr;
a:=1; writeln(' 1) ',a+f(a));
writeln(' 2) ',f(a)+a);
b:=2; writeln(' 3) ',g(b)=g(b))
Пример 4.
program exzampl4;
var c:char;
procedure p(x,y:char);
y:=succ(x)
end;
procedure q(x:char;var y:char);
y:=succ(x)
end;
{ ********** main program *********** }
c:='+'; p('2',c);
writeln(' 1) ',c);
c:='+'; q('2',c);
writeln(' 20 ',c)
Пример 5.
program exzampl5;
var a,b,c:integer;
procedure p(var x,y:integer);
var c:integer;
c:=x; x:=y; y:=c
end;
procedure q(var x,y:integer);
c:=x; x:=y; y:=c
end;
{ ********** main program ************ }
a:=1; b:=2; c:=3;
p(a,b); writeln('a=',a,' b=',b,' c=',c);
a:=1; b:=2; c:=3;
q(a,b); writeln('a=',a,' b=',b,' c=',c);
Пример 6.
program exzampl6;
var a:integer;
function f(x:real):real;
f:=x;
if x<0 then f:=f+1
end;
procedure p(var x,y:real);
x:=x*y
end;
{ ********** main program ************* }
p(a,f(-7)); writeln('a=',a)