- •1.1. Основные этапы создания программы
- •1.2. Алгоритмы
- •2.1. Структура типов в Turbo Pascal
- •Стандартные скалярные типы. Типы целых чисел
- •2.3. Операции побитовой обработки
- •2.4. Представление вещественных чисел в эвм
- •2.5. Символьный тип
- •2.6. Булевский тип
- •2.7. Перечисленный тип
- •2.8. Интервальный тип (диапазон)
- •3.1. Структура программы на turbo pascal
- •3.2. Основные операторы языка
- •3.2.1. Простые операторы
- •3.2.2. Операторы ввода-вывода
- •3.2.3. Структурные операторы
- •3.2.4. Условные операторы
- •3.2.5. Операторы повтора (цикла)
- •4.1. Массивы
- •4.2. Строковый тип
- •4.3. Множества
- •5.1. Процедуры и функции
- •5.2. Процедуры и функции пользователя
- •5.3. Передача параметров по значению и по ссылке
- •5.4. Рекурсивные процедуры и функции
- •6.1. Структура модулей
- •6.2. Компиляция и использование модулей
- •7.1. Записи
- •7.2. Вложенные записи
- •7.3. Записи с вариантами (вариантные записи)
- •7.4. Файлы
- •7.5. Подпрограммы для работы с файлами
- •7.5.1. Процедуры
- •7.5.2. Функции
- •7.6. Примеры программ для обработки файлов
- •7.7. Текстовые файлы
- •8.1. Структура оперативной памяти для программ на Turbo Pascal
- •8.2. Динамические структуры данных
- •8.3. Основные процедуры и функции для работы с динамическими переменными
- •8.4. Динамика выделения памяти в куче
- •8.5. Линейные списки. Способы создания и обработки
- •8.6. Нелинейные списки. Способы создания и обработки
- •Библиографический список
- •Оглавление
- •394026 Воронеж, Московский просп., 14
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);