Пример 1. Составить консольное приложение, выполняющее обработку матриц по формуле (A + B) ЧC + D. Приложение должно использовать модули Unit1 и Unit2, подготовленные в проек-
те и хранящиеся в одной папке с основной программой. Модуль Unit1 предназначен для объявления типа массивов, которые будут хранить матрицы, участвующие в вычислениях, и две процедуры: ReadMatr ввода матрицы и WriteMatr вывода. Модуль Unit2 также должен содержать процедуры AddMatr сложения матриц и MulMatr умножения. Требования к модулю Unit1. Для хранения матриц следует использовать двумерные динамические массивы. Первый параметр процедуры ReadMatr должен представлять матрицу, размеры которой заданы вторым и третьим параметрами, а четвертый параметр целого типа с начальным значением 0 указывать режим работы процедуры. Процедура ReadMatr должна обеспечить ввод матрицы с клавиатуры в виде матрицы по строкам, если четвертый параметр при ее вызове опущен. Этот параметр предназначен для отладки программ, использующих модуль Unit1. При задании в вызове процедуры ReadMatr четвертого параметра, не равного 0, процедура должна генерировать матрицу случайных чисел от нуля до абсолютного значения этого параметра включительно, причем если он меньше нуля, то при многократных запусках программы генерироваться должны разные данные, иначе. одни и те же. Сгенерированные матрицы следует выводить в виде матрицы по строкам. Процедура WriteMatr должна иметь один параметр, представляющий матрицу, и обеспечивать ее вывод в виде матрицы по строкам с пробелом между числами не менее одного. Требования к модулю Unit2. Для хранения матриц следует использовать двумерные динамические массивы типа, объявленного в модуле Unit1. В процедурах AddMatr и MulMatr два первых параметра должны представлять только входные данные (матрицы, представляющие только исходные данные), а третий только выходные данные (результирующую матрицу).
Требования к основной программе. Использовать условную компиляцию, обеспечивающую при объявлении имени Debug директивой {$IFDEF Debug} генерацию случайных чисел для матриц,
представляющих исходные данные, иначе. ввод матриц с клавиатуры.
//Модуль Unit1 объявления типа двумерного
//динамического массива
//и процедур ввода и вывода матриц.
unit Unit1;
interface
uses
Math;
type
tm1=array of Integer;
//тип двумерного динамического массива
tm2=array of tm1;
procedure ReadMatr(out x:tm2;
m, n:Integer;
r:Integer=0);
procedure WriteMatr(const x:tm2);
implementation
procedure ReadMatr(out x:tm2;
m, n:Integer;
r:Integer=0);
{Ввод матрицы m*n по строкам в динамический
массив типа tm2: при r=0 - ввод с клавиатуры,
иначе - от датчика случайных чисел,
причем при r>0 - без Randomize,
иначе - с Randomize}
var i, j:Integer;
begin
//Установить размеры массива x
//равными размерам вводимой матрицы
SetLength(x, m,n);
if r=0 then begin
//Ввод матрицы с клавиатуры
for i:=0 to m-1 do begin
for j:=0 to n-1 do
Read (x[i, j]);
ReadLn
end;
end
231
else
begin
//Генерация матрицы случайных целых чисел,
//из интервала 0..r+1
if r<0 then //При r<0 будет создан
//новый набор случайных чисел для матрицы
Randomize;
r:=Abs(r)+1;
for i:=0 to m-1 do
for j:=0 to n-1 do
x[i, j]:=Random(r);
WriteMatr(x);
end;
end;//ReadMatr
procedure WriteMatr(const x:tm2);
{Вывод матрицы m*n по строкам
из динамического массива}
var i, j,m, n,xmax:Integer;
begin
m:=High(x);
n:=High(x[0]);
xmax:=Abs(x[1,1]);
for i:=0 to m do
for j:=0 to n do
if Abs(x[i, j])>xmax then
xmax:=Abs(x[i, j]);
for i:=0 to m do begin
for j:=0 to n do
Write (x[i, j]:Trunc(Log10(xmax))+2);
WriteLn;
end;
end;//WriteMatr
end.
//Модуль Unit2 объявления процедур
//сложения и умножения матриц
unit Unit2;
interface
uses
Unit1;
{Фактические параметры обеих процедур не могут быть одновременно и входными, и выходными}
procedure AddMatr(const x, y:tm2; out z:tm2);
procedure MulMatr(const x, y:tm2; out z:tm2);
implementation
procedure AddMatr(const x, y:tm2; out z:tm2);
{Процедура сложения матриц Z=X+Y}
var
i, j,m, n:Integer;
begin
m:=High(x); //m+1 - число строк в X, Y и Z
n:=High(x[0]);//n+1 - число столбцов в X, Y и Z
//Установить размеры массива z
//равными размерам матрицы Z
SetLength(z, m+1,n+1);
for i:=0 to m do
for j:=0 to n do
z[i, j]:=y[i, j]+x[i, j];
end;//AddMatr
procedure MulMatr(const x, y:tm2; out z:tm2);
{Процедура умножения матриц Z=X*Y}
var
i, j,m, n,l, k:Integer;
begin
// m+1 - число строк в X и Z столбцов в Y
m:=High(x);
// n+1 - число столбцов в X
n:=High(x[0]);
// l+1 - число столбцов в Y
l:=High(y[0]);
//Установить размеры массива z
//равными размерам матрицы Z
SetLength(z, m+1,l+1);
for i:=0 to m do
for j:=0 to l do begin
z[i, j]:=0;
for k:=0 to n do
z[i, j]:=z[i, j]+x[i, k]*y[k, j];
end;
end;//MulMatr
end.
//Основная программа вычисления матрицы E=(A+B)*C+D
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils,
Unit1 in 'Unit1.pas',
Unit2 in 'Unit2.pas';
//Объявление имени Debug,
//используемого при условной компиляции.
{$DEFINE Debug}
//Отменить объявление имени Debug можно,
//удалив строку с директивой {$DEFINE Debug}
//или превратив ее в комментарий: //{$DEFINE Debug}.
var
a, b,c, d,e, f,g:tm2;
begin
{$IFDEF Debug}
//Если имя Debug объявлено директивой
//{$DEFINE Debug}, то в исполняемую программу
//будут включены следующие операторы, обеспечивающие
//генерацию матриц случайных чисел и их вывод
WriteLn(' Mатрица A 2х3 целых случайных чисел ' ,'в диапазоне 0..7');
ReadMatr(a,2,3,8);
WriteLn(' Mатрица B 2х3 целых случайных чисел ' ,'в диапазоне 0..5');
ReadMatr(b,2,3,6);
WriteLn(' Mатрица C 3х4 целых случайных чисел ' ,'в диапазоне 0..8');
ReadMatr(c,3,4,-9);
WriteLn(' Mатрица D 2х4 целых случайных чисел ' ,'в диапазоне 0..8');
ReadMatr(d,2,4,9);
{$ELSE} //иначе, то есть если имя Debug
//не объявлено, то в исполняемую программу
//будут включены следующие операторы,
//обеспечивающие ввод матриц с клавиатуры.
WriteLn(' Введите матрицу A 2х3');
ReadMatr(a,2,3);
WriteLn(' Введите матрицу B 2х3');
ReadMatr(b,2,3);
WriteLn(' Введите матрицу C 3х4');
ReadMatr(c,3,4);
WriteLn(' Введите матрицу D 2х4');
ReadMatr(d,2,4);
{$ENDIF}
//Вычисление и вывод матриц
AddMatr(a, b,f);
WriteLn(' Mатрица F=(A+B)');
WriteMatr(f);
MulMatr(f, c,g);
WriteLn(' Mатрица G=(A+B)xC');
WriteMatr(g);
AddMatr(g, d,e);
WriteLn(' Mатрица E=(A+B)xC+D');
WriteMatr(e);
ReadLn;
end.
Лабораторная работа 8
Программирование алгоритмов обработки текста.
Строка представляет собой набор символов, заключённый в апострофы. Например: ′ abcdef ′ ′ Иванов. Константа типа char представляет собой символьную строку единичной длины. Значение типа ShortString – это так называемые короткие строки, длина которых не превышает 255 символов. Каждый символ занимает один байт, самый первый байт содержит число, указывающее длину строки. Каждый байт имеет свой порядковый номер. Первый байт, содержащий длину строки, имеет номер 0. По номеру символа можно получить доступ к его значению, указав номер символа в квадратных скобках после имени строки.
Например, для строки st, имеющей тип shortstring и значение st = ′ Object ′ , получим:
ord(st[0])=6, st[1]=′O′, st[2]=′b′, st[3]=′j′, st[4]=′e′, st[5]=′c′, st[6]=′t′.
Длина строки, хранящаяся в нулевом байте, представлена в символьном виде, поэтому для преобразования в число следует воспользоваться стандартной функцией ord, а обратно – функцией chr.
Короткая строка размещается компилятором в памяти компьютера до начала выполнения программы, т. е. статически.
Строка типа AnsiString располагается в памяти иначе. Сама переменная типа AnsiString занимает в памяти 4 байта и является указателем, т. е. содержит адрес той ячейки памяти, начиная с которой будет фактически располагаться символьная строка. Выделение места в памяти происходит на этапе выполнения программы, т. е. динамически. Программа сама определяет необходимую длину строки по заданному количеству символов, и операционная система выделяет нужный участок памяти. В конце строки размещается терминальный (завершающий ) нуль – символ #0 и так называемый счётчик ссылок, занимающий 4 байта. Счётчик ссылок позволяет экономить память. Например, если в программе имеется фрагмент:
……………………………………
var s1, s2 : ansistring;
……………………………………
s1:=′ stroka ′;
s2 := s1;
…………………………………..
то память для размещения переменной s2 не выделяется, а в переменную s2 помещается значение указателя из переменной s1. Счётчик ссылок в области памяти, связанной с переменной s1, увеличивает своё значение на 1 и станет равным 2. В программе может быть несколько переменных, ссылающихся на одну и ту же строку. Счётчик ссылок равняется количеству ссылающихся на строку переменных. Если одна из ссылающихся на строку типа AnsiString переменных изменит своё значение, то в памяти будет выделено место для новой строки. Число ссылок в прежней строке уменьшится на 1, а в новой строке становится равным 1. Если число ссылок на строку станет равным 0, то строка уничтожается и освобождает место в памяти. Нумерация символов в строке типа AnsiString начинается с 1. Процедура SetLength, которую мы использовали для установления длины динамического массива, может быть также использована для установления длины строки типа AnsiString.
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 |


