Главная » Free Pascal » Параметры подпрограмм — двумерные массивы Free Pascal

0

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

Процедура mat_add1 выполняет сложение двух квадратных матриц в традици- онном стиле ранних версий Паскаля (листинг 9.5).

   Листинг 9 .5 .  Процедура  mat_add1                                             

const

N=10;

type

matN = array [1..N,1..N] of integer; var

a, b, c: matN

procedure mat_add1(A,B:matN; var C:matN);

// Сложение квадратных матриц C=A+B var

i,j:integer; begin

for i:=1 to N do

for j:=1 to N do C[i,j]:=A[i,j]+B[i,j];

end;

Основным недостатком этой процедуры является то, что она "умеет" склады- вать только матрицы размером N´N при фиксированном значении N. Кроме того, два первых параметра являются значениями, и это обязывает компилятор перед вызовом процедуры mat_add1 копировать оба слагаемых в стек.

Процедура mat_add2 избавлена от этих недостатков за счет использования не-

типизированных формальных параметров (листинг 9.6).

   Листинг 9 .6 .  Процедура  mat_add2                                             

procedure mat_add2(var A,B,C; m:integer);

// Сложение квадратных матриц C=A+B var

x:array [0..0] of integer absolute A; y:array [0..0] of integer absolute B; z:array [0..0] of integer absolute C; i,j:integer;

begin

{$R-}

for i:=0 to m-1 do for j:=0 to m-1 do

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

{$R+}

end;

Еще одной изюминкой в процедуре mat_add2 является использование приве- денных индексов. Если бы внутренние массивы x, y и z были объявлены как дву- мерные, то смещение элемента с индексами [i, j] относительно начального эле- мента с индексами [0, 0] вычислялось бы по формуле i*m+j.

Следующая процедура mat_mul1 выполнена в соответствии с математическими правилами умножения квадратных матриц, однако ей присущи недостатки, отме- ченные в процедуре mat_add1 — загромождение стека, возможность перемножить матрицы единственного размера (листинг 9.7). Кроме того, бездумное использова- ние процедуры mat_mul1 может привести к ошибочному результату, и о такой ошибке никто программиста не предупредит.

   Листинг 9.7 .  Процедура  mat_mul1                                             

procedure mat_mul1(A,B:matN; var C:matN);

// Умножение квадратных матриц C=A*B

var

i,j,k:integer; s:integer;

begin

for i:=1 to N do for j:=1 to N do

begin

s:=0;

for k:=1 to N do s:=s+A[i,k]*B[k,j];

C[i,j]:=s;

end;

end;

Если третий аргумент не совпадает ни с первым, ни со вторым, то процедура mat_mul1 работает идеально правильно. Но если хотя бы одно из этих двух условий будет нарушено, то элементы одного из сомножителей в процессе работы подпро- граммы будут портиться, и общий результат окажется неверным.

Для того чтобы избавиться от недостатков процедуры mat_mul1, целесообразно воспользоваться двумерными динамическими массивами (листинг 9.8).

   Листинг 9 .8 .  Программа  mul_mat                                              

program mul_mat; type

dyn_ar2 = array of array of integer;

var

a,b,c : dyn_ar2;

i,j : integer;

procedure mat_mul2(A,B:dyn_ar2; var C:dyn_ar2); var

i,j,k:integer;

s:integer; begin

for i:=0 to High(A) do for j:=0 to High(A) do

begin

s:=0;

for k:=0 to High(A) do s:=s+A[i,k]*B[k,j];

C[i,j]:=s;

end;

end;

begin

SetLength(a,2,2);    {запрос памяти под первый сомножитель} SetLength(b,2,2);    {запрос памяти под второй сомножитель} SetLength(c,2,2);    {запрос памяти под результат} a[0,0]:=1;   a[0,1]:=2;

a[1,0]:=3;   a[1,1]:=4;

b[0,0]:=5;   b[0,1]:=6;

b[1,0]:=7;   b[1,1]:=8;

mat_mul2(a,b,c); for i:=0 to 1 do

begin

for j:=0 to 1 do write(c[i,j]:4); writeln;

end; readln;

end.

Результаты работы программы mul_mat приведены на рис. 9.3.

Рис. 9.3. Результат умножения матриц

Единственное, что было бы полезно добавить к процедуре mat_mul2, так это сравнение указателя C с указателями A и B. В случае хотя бы одного совпадения мож- но было бы выдать сообщение о недопустимом формате обращения к процедуре.

Источник: Кетков, Ю. Л., Свободное программное обеспечение. FREE PASCAL для студентов и школьников, Ю. Л. Кетков, А. Ю. Кетков. — СПб.: БХВ-Петербург, 2011. — 384 с.: ил. + CD-ROM — (ИиИКТ)

По теме:

  • Комментарии