Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Praktikum_po_programmirovaniyu.doc
Скачиваний:
23
Добавлен:
09.12.2018
Размер:
2.5 Mб
Скачать

5.3. Передача параметров по значению и по ссылке

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

В Паскале существует два способа передачи параметров в подпрограммы: передача параметров по значению и передача параметров по ссылке.

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

Таким образом, переменные, передаваемые по значению, полностью защищены от искажений. Однако такой способ передачи приводит к значительным затратам памяти и требует дополнительного времени на перезаписывание.

При передаче параметров по ссылке в стек записывается не значение переменной, а ее адрес, который может занимать два или четыре байта. Таким образом, процедура или

82

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

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

Оформим в виде процедур:

- ввод матриц с клавиатуры;

- вывод введенных матриц на экран;

- сложение матриц;

- уможение матриц.

Расчет нормы матрицы оформим в виде функции.

Program matr;

type mas= array[1..10,1..10]of integer;

var

a, b, c, w: mas;

p1, p2, p3, p: real;

n: integer;

im1, im2, im3:string;

{Процедура ввода матрицы. Все параметры должны быть} {возвращены в вызывающую программу, поэтому они определены,}

{ как параметры-переменные}

83

Procedure intp(var name: string; var m: integer; var x: mas);

var i, j:integer;

begin

writeln('Введите имя матрицы');

readln(name);

writeln('Введите размерность матрицы');

readln(m);

for i: = 1 to m do

begin

for j: = 1 to m do

begin

writeln(‘Введите элементы матрицы’);

readln(x[i,j]);

end;

end;

end;

{Процедура вывода на экран элементов матрицы.}

{ Все параметры определены как параметры-значения}

Procedure outp(name: string; m: integer; x: mas);

var i,j: integer;

begin

writeln(‘Матрица ’,name);

for i: = 1 to m do

begin

for j: = 1 to m do

begin

write(x[i,j],' ');

end;

writeln;

end;

end;

{Процедура сложения двух матриц. Параметры m, x, y,} {передаваемые в процедуру, определены как}

84

{параметры-значения, результат z, возвращаемый}

{ в головную программу, определен как}

{ параметр-переменная}

Procedure sum(m: integer; x,y: mas; var z: mas);

var i,j: integer;

begin

for i: = 1 to m do

for j: = 1 to m do

z[i,j]: = x[i,j] + y[i,j];

end;

{Процедура умножения двух матриц}

Procedure mult(m:integer; x,y:mas; var z:mas);

var i, j, k: integer;

begin

for i: = 1 to m do

begin

for j: = 1 to m do

begin

z[i,j]: = 0;

for k: = 1 to m do

begin

z[i,j]: = z[i,j] + x[i,k] * y[k,j];

end;

end;

end;

end;

{Функция расчета нормы. Результат возвращается по}

{ имени функции.}

Function norma(m: integer; x: mas): integer;

var i,j,d: integer;

85

begin

d:=0;

for i: = 1 to m do

begin

for j: = 1 to m do

begin

d: = d + abs(x[i,j]);

end;

end;

norma:=d;

end;

begin

intp(im1,n,a); {Ввод матрицы A}

intp(im2,n,b); {Ввод матрицы B}

intp(im3,n,c); {Ввод матрицы C}

outp(im1,n,a); {Вывод матрицы A}

outp(im2,n,b); {Вывод матрицы B}

outp(im3,n,c); {Вывод матрицы C}

{Обращение к процедуре суммирования. Вычисляется сумма} {матриц a,b и результат помещается в матрицу w }

sum(n,a,b,w);

{Обращение к процедуре суммирования. К матрице w, }

{полученной при предыдущем обращении, прибавляется}

{ матрица c. Результат снова помещается в матрицу w }

sum(n,w,c,w);

{Обращение к функции для расчета нормы матрицы,}

{ являющейся суммой матриц a, b, c}

p1:=norma(n,w);

{Обращение к процедуре умножения. Находится произведение} {матриц a,b и результат помещается в матрицу w }

mult(n,a,b,w);

p2:=norma(n,w);

86

mult(n,b,c,w);

sum(n,w,a,w);

p3:=norma(n,w);

p:=(p1+p2)/p3;

writeln(‘Результат = ’, p);

end.

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

Procedure fakt(const m: integer; x: byte, var y: real);