Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование


Скачать 1.17 Mb.
Название Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование
страница 3/8
Тип Конспект
rykovodstvo.ru > Руководство эксплуатация > Конспект
1   2   3   4   5   6   7   8


Рис.A: Пример с TShape

Во втором примере (проект PIXELS.DPR, рис.2) показано, как осуществить доступ к отдельной точке на изображении (на канве). По нажатию кнопки "Fill" всем точкам изображения присваивается свой цвет:

procedure TForm1.Button1Click(Sender: TObject);

var

i, j : Longint;

begin

Button1.Enabled:=False;

with Canvas do

for i:=1 to Width do begin

Application.ProcessMessages;

for j:=1 to Height do

Pixels[i,j]:=i*j;

end;

Button1.Enabled:=True;

end;



Рис.B: Работа с точками на канве.

В третьей программе (проект DRAW.DPR, рис.3) приведен пример использования методов, выводящих изображение - Draw и StretchDraw:



Рис.C: Вывод изображений на канву.

Прорисовка изображений происходит в обработчике события OnPaint для формы:

procedure TForm1.FormPaint(Sender: TObject);

begin

with Canvas do begin

Draw(0,0, Image1.Picture.BitMap);

StretchDraw(Rect(250,0,350,50),Image1.Picture.BitMap)

end;

end;

2.2 Структурное и модульное программирование в Delphi

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

разных частей программы для обработки разных данных.Использование подпрограмм позволяет уменьшить размер про-граммы (если в различных частях программы необходимо выполнять обработку данных по одному алгоритму) и сделать ее исход-ный текст более удобным для понимания процесса обработки дан-ных (если алгоритм подпрограммы обладает функциональной законченностью, а имя подпрограммы отражает ее назначение, как,например, у стандартных подпрограмм Sin(X) или Abs(X)). Пре-имущества использования подпрограмм проявляются также приразработке больших программ, так как становится возможным распараллелить процесс создания программного продукта, поручив разработку отдельных подпрограмм разным исполнителям, и, что

более важно, . упростить процесс написания и отладки. Разбиение программы на подпрограммы производится прежде всего по функциональному признаку: подпрограмма должна реализовывать одну, но законченную функцию. При этом надо стремиться к сокращению количества межпрограммных связей (количеству передаваемых параметров). Рекомендуемый размер подпрограммы составляет 10.60 строк текста. Нецелесообразно создавать слишком короткие подпрограммы, а размещение подпрограммы в пределах одной страницы позволит программисту охватить весь текст одним взглядом и не тратить время на переключение внимания с одной страницы на другую. В языке Object Pascal используются два вида подпрограмм . функции и процедуры. При общих принципах оформления функции обладают дополнительными возможностями. Поэтому сна-

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

Процедуры. При работе с подпрограммами следует различать термины объявление подпрограммы (описание подпрограммы) и обращение к подпрограмме (вызов подпрограммы). Объявление подпрограммы содержит ее имя и описывает процесс обработки данных, представленных параметрами (пока будем считать так, следуя рекомендациям структурного программирования). В объявлении подпрограммы параметры называют формальными. Имя подпрограммы задает ее разработчик, и оно должно быть уникальным в своем блоке. Обращение к подпрограмме выполняется по ее имени и описывает данные (фактические параметры), обработку которых она должна выполнить. Выполнение обращения приводит к передаче управления подпрограмме. Вызовов одной подпрограммы может быть несколько, а фактические параметры в них . разными. Объявления подпрограмм и их вызовы должны оформляться в соответствии с правилами, которые будут представлены в виде синтаксических диаграмм. Имя процедуры (рис. 6.1) строится так же, как и прочие имена в языке Object Pascal. Блок процедуры, как и блок основной программы, может содержать объявления меток, констант, типов, переменных, подпрограмм и обязательно . составной оператор (begin .... end), представляющий алгоритм. Список формальных параметров содержит имена, используемые в теле подпрограммы для описания процесса обработки данных.

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

Пример объявления и вызова процедуры, выводящей на экран

первое из двух значений, представленных параметрами, кратное 5,

или сообщение, что кратных нет:

//Объявление процедуры

procedure PutMod5(I,J:Integer);

// I и J . формальные параметры

begin

if I mod 5 = 0 then

WriteLn(I)

else if J mod 5 = 0 then

WriteLn(J)

else

WriteLn('Нет параметров, кратных 5');

end;

. . . . .

begin // РАЗДЕЛ ОПЕРАТОРОВ ПРОГРАММЫ

. . . . .

//Вызов процедуры

PutMod5(A+3, B);//A+3 и B . фактические параметры

. . . . .

end.

Рассмотрим на конкретных значениях переменных A и B, что будет выведено подпрограммой:

при A = 2 и B = 10 будет выведено значение 5;

при A = 3 и B = 10 будет выведено значение 10;

при A = 3 и B = 11 будет выведен текст «Нет параметров, крат-

ных 5».

Тип в объявлении формального параметра пока будем считать обязательным и задавать только именем ранее объявленного или стандартного типа (другие возможности будут рассмотре-

ны позже).Прежде чем перейти к пояснению правил объявления формальных параметров, введем в рассмотрение два термина: входной параметр и выходной параметр. Параметр считается входным,

если он представляет исходные данные для счета по алгоритму подпрограммы (в рассмотренном примере оба параметра являются входными). Параметр считается выходным, если он представляет результаты счета по подпрограмме. Допускается, что один и тот же параметр может одновременно представлять и исходные данные, и результат, т. е. быть одновременно и входным, и выходным.

В языке Object Pascal рассмотренное функциональное деление параметров (на входные, выходные, входные-выходные) дополнено механизмами реализации их функций, отраженными в правилах объявления формальных параметров. Сначала рассмотрим два вида объявлений параметров: параметры-значения и параметры-переменные.Параметры-значения всегда являются только входными параметрами. Соответствующими фактическими параметрами могут быть выражения (в частности, константы и переменные). При вызове подпрограммы выражения вычисляются и полученные значения заносятся (а значения констант и переменных просто копируются) в ячейки памяти, представленные соответствующими формальными параметрами, значения которых внутри подпрограммы можно изменять. Механизм параметров-значений таков, что эти изменения никак не отразятся на значениях фактических параметров, т. е. после выхода из подпрограммы они останутся неизменными. Таким образом, формальный параметр-значение можно рассматривать как переменную, известную внутри подпрограммы,а механизм таких параметров . как защиту фактических параметров, если они переменные, от непреднамеренного изменения.Объявление параметров-значений дается просто их именем (списком имен через запятую) и типом (без предшествующих слов var, const, out). В рассмотренной процедуре PutMod5 оба параметра представляют собой параметры-значения. Параметры-переменные являются одновременно и входными, и выходными параметрами. Соответствующими фактическими параметрами могут быть только переменные. Механизм параметров-переменных таков, что изменения, выполняемые в алгоритме подпрограммы над соответствующими формальными параметрами, приводят к изменению значений фактических, и эти изменения сохранятся после выхода из подпрограммы. Достигается это

за счет того, что в подпрограмму передается не сама переменная, а ссылка на нее, т. е. обеспечивается непосредственный доступ из подпрограммы к данным фактического параметра. Объявление параметров-переменных дается с предшествующим их имени (списку имен) словом var и типом.

Пример процедуры, умножающей данные в первых n ячейках массива Mas на дробную часть числа R (все участвующие в обработке данные должны передаваться через параметры):

type tMas=array[1..8] of Real;

. . . . .

//Объявление процедуры

procedure MasMulR(R:Real; N:Integer; var Mas:tMas);

var

i:Integer;

begin

R:=Frac(R);//Получить дробную часть R

for i:=1 to N do

Mas[i]:=Mas[i]*R;

end;//MasMulR . конец текста процедуры

. . . . .

var

X:tMas=(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);

Z:Real=3.4;

. . . . .

begin // РАЗДЕЛ ОПЕРАТОРОВ ПРОГРАММЫ

. . . . .

MasMulR(Z,5,X);//Вызов процедуры

. . . . .

end.

В этом примере Mas является и входным, и выходным, поэтому он объявлен как параметр-переменная (с предшествующим словом var). Параметр R . только входной. Так как он объявлен как параметр-значение, то его после использования в качестве входного данного можно менять внутри подпрограммы, т. е. ис пользовать как дополнительную переменную, не опасаясь, что изменится значение соответствующего фактического параметра. При указанных в примере начальных значениях переменных после выполнения процедуры переменная Z сохранит свое значение 3.4, а в массиве будут следующие данные: 0.4, 0.8, 1.2, 1.6, 2.0, 6.0, 7.0, 8.0. Параметры-значения обладают одним недостатком, который может оказаться очень существенным, если параметром является

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

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

копирование данных перед началом их обработки по алгоритму подпрограммы. Указанных недостатков лишен другой вид входного параметра, получивший название «параметр-константа».

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

и для параметра-переменной), но для исключения непреднамеренного изменения во время работы программы уже на этапе компиляции выполняют соответствующие проверки. Исполняемая

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

их имени (списку имен) словом const и типом. Последний вид параметра следует использовать для параметров, представляющих только результаты работы подпрограммы. По аналогии с параметрами других видов ему подошло бы название параметр-результат или по предшествующему его име-

ни слову out в объявлении . параметр-выходная переменная. Этот параметр передается по ссылке, но компилятор не запрещает его использование в качестве источника исходных данных. За этим

должен следить программист, а слово out перед именем в списке формальных параметров призвано облегчить понимание алгоритма подпрограммы, напоминая, что параметр не представляет

входных данных. Пример процедуры, в объявлении которой желательно использовать параметр-константу и параметр-результат. Подпрограмма должна вычислять сумму положительных элементов массива X(100, 100) и их количество:

type

tMas=array[1..100,1..100] of Extended;

. . . . .

//Объявление процедуры

procedure SumCol(const X:tMas,

out S: Extended;

out K:Integer);

var

i,j: Integer;

begin

S:=0;

K:=0;

for i:=1 to 100 do

for j:=1 to 100 do

if X[i,j]>0 then

begin

S:=S+X[i,j];

K:=K+1;

end;

end;

. . . . .

var

Y:tMas; Sum: Extended; Col: Integer;

. . . . .

begin // РАЗДЕЛ ОПЕРАТОРОВ ПРОГРАММЫ

. . . . .

SumCol(Y,Sum,Col);

. . . . .

end.

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

стантой, а не параметром-значением, чтобы избежать выделения памяти в 100 000 байт и копирования в нее данных из фактического параметра . массива Y. 6.2. Пример выполнения задания Составить процедуру, копирующую из матрицы A(m, n), m Ј 10, n Ј 14 положительные элементы в массив Pol и подсчитывающую их количество kPol, а отрицательные элементы . в массив Otr и подсчитывающую их количество kOtr. Использовать эту процедуру для матрицы В в основной программе. Если окажется, что положительных и/или отрицательных элементов в матрице нет, то вывести соответствующие сообщения, иначе скопированные в массивы данные:

program Project1;

{$APPTYPE CONSOLE}

uses

SysUtils;

const

mMax=10; nMax=14;

179

type

tMatr=array[1.. mMax,1.. nMax] of Real;

tMas=array[1.. mMax * nMax] of Real;

procedure PolOtr(const A:tMatr;

m,n:Integer;

out Pol, Otr:tMas;

out kPol, kOtr:Integer);

var

i,j:Integer;

begin

kPol:=0;

kOtr:=0;

for i:=1 to m do

for j:=1 to n do

begin

if A[i,j]>0 then

begin

kPol:= kPol +1;

Pol[kPol]:=A[i,j];

end

else if A[i,j]<0 then

begin

kOtr:= kOtr +1;

Otr[kOtr]:=A[i,j];

end;

end;

end;

var

B:tMatr; P,O:tMas;

m,n,i,j,kP,kO:Integer;

begin // РАЗДЕЛ ОПЕРАТОРОВ ПРОГРАММЫ

WriteLn('Введите количество строк и столбцов');

ReadLn(m,n);

WriteLn('Введите матрицу по строкам');

for i:=1 to m do

begin

for j:=1 to n do

Read(B[i,j]);

6

ReadLn;

end;

PolOtr(B,m,n,P,O,kP,kO);

if kP>0 then

begin

WriteLn(' Массив положительных');

for i:=1 to kP do

Write(P[i]:6:1,' ');

end

else

WriteLn('Положительных элементов нет');

WriteLn;

if kO>0 then

begin

WriteLn(' Массив отрицательных');

for i:=1 to kO do

Write(O[i]:6:1,' ');

end

else

WriteLn('Отрицательных элементов нет');

ReadLn;

end.

Функции.

Отличие функции от процедуры состоит в том, что: в заголовке после списка параметров необходимо указать тип функции (т. е. тип вычисляемого ею результата) . имя ранее объявленного или стандартного типа; . в вызывающей программе обращение к функции можно записывать в правой части оператора присваивания и в выражениях, если тип результата простой (но присваивать значение имени функции в вызывающей программе запрещено); . в объявлении функции ее имя (не обращение, делающее подпрограмму рекурсивной) не должно встречаться в правой части операторов присваивания или в выражениях; . в объявлении функции должен быть хотя бы один оператор, присваивающий ее имени или объявленной по умолчанию локальной (известной только внутри функции) переменной Result того же типа, что и тип функции, результат вычислений; . в отличие от имени переменную Result можно использовать в правых частях операторов присваивания и в выражениях как дополнительную переменную, представляющую результат вычислений. Обращение к функции, как и к процедуре, можно записывать как отдельный оператор в режиме расширенного синтаксиса, используемом в Delphi по умолчанию. Обращение к функции отдельным оператором имеет смысл, когда интересующий нас результат представлен параметрами, а не именем функции. Отключить режим расширенного синтаксиса можно директивой {$X-} или {$EXTENDEDSYNTAX OFF}, но тогда не будет объявлена по умолчанию локальная переменная Result и при попытке ее

использования компилятор сообщит об ошибке. Пример 1. Составить и использовать функцию, возвращающую

максимальный из первых N элементов массива X(N), N Ј 100:

type

tMas=array[1..100] of Real;

. . . . .

function MaxMas(N:Integer; const X:tMas):Real;

var

i:Integer;

begin

Result:=X[1];

for i:=2 to N do

if X[i]>Result then

Result:=X[i];

end;

. . . . .

var

Y:tMas;

begin // РАЗДЕЛ ОПЕРАТОРОВ ПРОГРАММЫ

. . . . .

//Вызов функции в операторе вывода

WriteLn('Максимальный из сорока '

,'элементов массива Y = '

,MaxMas(40, Y));

. . . . .

end.

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

function MaxMas(N:Integer; const X:tMas):Real;

var

i:Integer;

R:Real;//Дополнительная переменная

begin

R:=X[1];

for i:=2 to N do

if X[i]>R then

R:=X[i];

//Чтобы функция возвратила вычисленное значение,

//оно должно быть присвоено ее имени

MaxMas:=R;

end;

Использование функций позволяет не только сделать текст программы более удобным для понимания алгоритма, но и уменьшить его при необходимости повторных вычислений в разных частях программы.

Приложение Delphi помимо стандартных модулей может использовать модули, создаваемые пользователями. Каждый модуль пользователя является отдельно подготовленной и хранящейся в

отдельном файле с расширением .pas программной единицей, которая может быть использована любой программой. В Delphi реализован модульный принцип программирования, причем модули играют роль наборов заранее подготовленных и отлаженных подпрограмм, именованных констант, типов, переменных, которые могут использоваться в тех частях программы (в основной программе и модулях).

Модули также могут содержать код, выполняемый до передачи управления в указанные части программы, и код, выполняемый после возврата управления из них. Любая часть модуля может быть пустой, однако ключевые слова interface и implementation опускать нельзя. Если в модуле

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

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

пользует данный модуль), а часть финализации . для операторов, выполняемых после окончания основной (указанной части) программы. Например, в части инициализации можно создать временные файлы для хранения данных только во время выполнения программы, а в части финализации удалить эти файлы. Такое решение позволит упростить разработку программы и избежать засорения дискового пространства ненужными файлами при возникновении исключений в основной программе,

так как часть финализации будет выполнена в любом случае. Например, если модуль Unit1, в котором создается файл 'TempFile.txt':

unit Unit1;

interface

var

//Файловая переменная f будет представлять

//временный файл в программе,

//использующей данный модуль

f: TextFile;

implementation

initialization

//Связать файловую переменную f

//с внешним именем файла 'TempFile.txt'

Assign(f, 'TempFile.txt');

Rewrite(f); //создать файл

finalization

if FileExists('TempFile.txt') then

//Если файл не был уничтожен,

begin //то

try

CloseFile(f); //Закрыть файл

except

//Сообщения не будет,

//если файл был закрыт в основной программе

end;

Erase(f); //Уничтожить закрытый файл

end

end.

. присоединить к программе Project1:

program Project1;

{$APPTYPE CONSOLE}

uses

SysUtils,

Unit1;//Использовать модуль Unit1 в этой программе

. . . . . . .

то файл 'TempFile.txt' будет создан до передачи управления в основную программу и с ним можно будет работать, используя файловую переменную f (открывать, закрывать, открывать для до-

бавления текста, записывать текст в файл, читать из файла, уничтожать файл), а после выхода из основной программы при любом ее завершении (нормальном или аварийном) управление

будет передано операторам части финализации модуля Unit1, и файл 'TempFile.txt' будет уничтожен.

Объявления в отдельных частях модуля могут располагаться в любой последовательности и чередоваться при соблюдении правила использования имен: при объявлении нового имени (констан-

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

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

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

uses Math;

Присутствие имени модуля в предложении использования основной программы (или другого модуля) означает, что объявленные в его интерфейсной части константы, типы, переменные и подпрограммы доступны для использования. Существует отличие в назначении предложений использования в разных частях модуля. Предложения использования в интерфейсных частях должны строиться так, чтобы не возникало взаимных ссылок модулей непосредственно или через другие модули. Только в этом случае компилятор сможет определить порядок использования объявлений из интерфейсных частей.Для части реализации такого ограничения нет. Это позволяет строить взаимно рекурсивные подпрограммы, принадлежащие разным модулям. Можно использовать взаимную рекурсию и внут-

ри модуля без применения директивы forward, так как оно действует в модулях по умолчанию для всех подпрограмм, заголовки которых размещены в интерфейсной части. При разработке программы в среде Delphi вновь создаваемый модуль (по команде File/New/Unit) добавляется в предложение использования основной программы автоматически. Также автоматически добавляется в предложение использования основной программы ссылка на готовый модуль. Для этого следует ввести команду Project/Add to Project..., в диалоге выбрать папку с модулем и в ней . сам модуль с расширением .pas (при разработке приложения с формой текст основной программы можно отобразить командой Project/View Source). После добавления в проект модулей программист уже в них должен прописать в предложениях использования взаимные ссылки. В приложениях с формой убедиться, что модуль подключен, можно, отобразив текст основной программы командой Project/View Source, где должна быть ссылка на модуль в предложении uses, или открыв окно диалога Project Manager командой View/Project Manager... Пример 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);

7. МОДУЛИ ПОЛЬЗОВАТЕЛЕЙ

232 ПРАКТИКУМ ПО ПРОГРАММИРОВАНИЮ

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}

233

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}

7. МОДУЛИ ПОЛЬЗОВАТЕЛЕЙ

234 ПРАКТИКУМ ПО ПРОГРАММИРОВАНИЮ

Рис. 7.2

//Вычисление и вывод матриц

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.

При запуске программы с директивой, объявляющей имя Debug, в окно программы сразу будут выведены результаты построения матриц случайных чисел с поясняющими текстами и вычисления (A + B)ЧC + D по шагам, как показано на рис. 7.2. При повторных запусках программы матрицы A и B не изменятся, а C и D будут создаваться всякий раз новые, так как генерация новых случайных чисел стандартной функцией Random начинается с вызова ReadMatr(c,3,4,-9) для построения матрицы C, где отрицательное значение последнего параметра требует выполнения процедуры Randomize. После отладки программы строку с директивой {$DEFINE Debug} следует превратить в комментарий.

К Unit1 должен подключаться стандартный модуль Math, так как в процедуре WriteMatr используется стандартная процедура Log10, но поскольку объявления интерфейсной части Unit1 не требуют подключения Math, то предложение использования uses Math; размещено в его части реализации.

Модуль Unit1 должен быть под ключен к Unit2 в интерфейсной части, так как объявленный в Unit1 тип tm2 двумерного динамического массива используется при объявлении заголов-

ков процедур AddMatr и MulMatr. Следует обратить внимание на одну особенность динамичес-

ких массивов при работе с матрицами, использованную в процедурах WriteMatr, AddMatr и MulMatr, . размеры массивов всегда совпадают с размерами матриц, что исключает необходимость указания их в качестве параметров подпрограмм. В соответствии с условиями примера 1 входные параметры

объявлены как const-параметры, а выходные . как out-параметры.

При наличии в разных модулях одинаковых имен, объявленных в их интерфейсных частях, использование их подчиняетсяследующему правилу: для избежания ошибок перед именем в ка-

честве префикса следует использовать имя модуля, если оно использовано без префикса, то будет отнесено к модулю, указанному в предложении использования последним, где это имя было объяв-

лено. Так, в основной программе последним в предложении использования был модуль Unit3, поэтому вызовы его процедурыMulMatr записаны без префиксов (например, MulMatr(a,b,b)), а

вызовы процедур модуля Unit2 . с префиксом (например,Unit2.MulMatr(a,d,c)).


2.3. Объектно-ориентированный подход к проектированию прикладных программ

Объектно-ориентированное программирование (ООП) — это технология, основанная на представлении программ в виде со­вокупности объектов, каждый из которых является реализа­цией собственного класса, которые в свою очередь образуют иерархию на принципах наследования.

Основное достоинство ООП — сокращение количества меж­модульных вызовов и уменьшение объемов информации, пере­даваемой между модулями, по сравнению с модульным про­граммированием. Это достигается посредством более полной локализации данных и интегрирования их с подпрограммами обработки, что позволяет вести практически независимую раз­работку отдельных частей (объектов) программы.

Объектная декомпозиция

При использовании технологии ООП решение представляет­ся в виде результата взаимодействия отдельных элементов не­которой системы, имитирующей процессы, происходящие в предметной области поставленной задачи. Каждый элемент си­стемы, получая сообщение, выполняет заранее определенную последовательность действий (например, обрабатывает полу­ченные данные, изменяет свое состояние, пересылает получен­ные данные другому элементу системы). Передавая сообщения от одного элемента системы к другому, система выполняет по­ставленную перед ней задачу.

Элементы системы, параметры и поведение которой опреде­ляются условием задачи, обладающие самостоятельным пове­дением (т. е. «умеющие» выполнять некоторые действия, завися­щие от полученных сообщений и состояния элемента), получили название объектов .

Процесс представления предметной области в виде совокуп­ности объектов, обменивающихся сообщениями, называется объ­ектной декомпозицией.

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

Основная цель системы — нарисовать фигуру, выбранную пользователем. Действия пользователя — это либо выбор фигу­ры, либо изменение параметров фигуры (цвет, размер, коорди­наты), либо команда нарисовать выбранную фигуру с заданными параметрами. Для выполнения этих команд можно воспользова­ться следующими объектами: Менеджер (получает, анализиру­ет и обрабатывает команды пользователя) и три объекта — фи­гуры (каждая со своими параметрами).

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

В объектно-ориентированном программировании разрабаты­ваемая система состоит из объектов, которые взаимодействуют через передачу сообщений.

Каждый объект, получив сообщение, должен определен­ным образом реагировать на них, выполняя заранее опреде­ленные для каждого типа сообщения действия. Например, если объект ОбработатьЗапись будет активизирован, то он дол­жен будет проанализировать, какое именно действие нужно выполнить. Если принято сообщение Редактировать, то объ­ект должен сохранить запись в файл, на место, указанное кур­сором.

Состояние объекта характеризуется набором конкретных значений некоторого перечня всех возможных свойств данно­го объекта; например, состояние объекта Файл характеризует­ся значениями «активизирован» — «не активизирован». Это состояние объекта необходимо для выполнения всех действий над записной книжкой: если Файл находится в состоянии «не активизирован», то ни одно сообщение не сможет быть обрабо­тано.

Набор значений свойств задается на этапе проектирования и не изменяется в процессе функционирования, изменяются лишь конкретные значения.

Поведение объектов характеризуется определенным набо­ром реакций на получаемые сообщения и зависит от состояния объекта.

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

Обращение к объекту для изменения его состояния возбуж­дает выполнение операции модификации. Отправитель сообще­ния-команды, реакцией на которую должна быть модификация объекта, может ожидать завершения операции, а может про­должить выполнение своей программы.

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

Основные элементы ООП

ООП характеризуется четырьмя основополагающими идея­ми (абстрагирование, инкапсуляция, модульность, иерархия) и тремя дополнительными (типизация, параллелелизм, сохраня­емость).

Абстрагирование — это один из главных способов решения сложных задач.

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

Для представления абстракций объектов используется спе­циальный определяемый программистом тип данных — класс.

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

Итак, сочетание данных с допустимыми действиями над этими данными приводит к «рождению» нового «кирпичика» программирования — класса. Действия — это процедуры и функции, описанные в классе, они получили название методов.

Класс представляет собой структуру, динамически размеща­емую в памяти. Экземпляр класса называется объектом. Преж­де чем программа сможет использовать объект какого-либо класса, его необходимо создать. Объекты создаются и уничто­жаются с помощью специальных методов, которые называются constructor (конструктор) и destructor (деструктор).

«Рожденный ползать летать не может» — и объект действу­ет только так, как это в нем заложено, и только над тем, что в нем описано. Обращение к данным объекта не через его методы недопустимо.

Для корректной работы абстракции доступ к ее внутренней структуре должен быть ограничен. Для этого вводятся две час­ти в описании абстракции.

Интерфейс — это совокупность доступных извне элементов реализации абстракции, т. е. основные характеристики состоя­ния и поведения.

Реализация — это совокупность недоступных извне элемен­тов реализации абстракции, т. е. внутренняя организация абст­ракции и механизмы реализации ее поведения.

Наличие интерфейса обеспечивает уменьшение возможности «разрушения» (несанкционированного изменения значений по­лей) объекта извне. При этом сокрытие особенностей реализа­ции упрощает внесение изменений в реализацию класса как в процессе отладки, так и при модификации программы. Таким образом, класс определяет существование глобальной области данных внутри объекта, доступной методам объекта. С другой стороны, доступ к объекту регламентируется и должен выпол­няться через специальный интерфейс.

Для описания нового класса в языке Object Pascal определен следующий синтаксис:

Туре <�имя_объявляемого_класса>=с1аss(<�имя_класса_родителя>) Private

<�скрытые_элементы_класса> Protected

<�защищенные_элементы_класса> Public

<�общедоступные_элементы_класса> Published

<�опубликованные_элементы_класса> end;

Директивы private, protected, public, published пред­назначены для ограничения доступа к элементам класса.

Секция private содержит внутренние элементы, обращение к которым возможно только в пределах модуля, содержащего объявление класса.

Секция protected содержит защищенные элементы, кото­рые доступны в пределах модуля, содержащего определение класса, и внутри классов-потомков.

Секция public содержит общедоступные элементы, к кото­рым возможно обращение из любой части программы.

Секция published содержит опубликованные элементы, ко­торые по ограничению доступа аналогичны public. Для визуаль­ных компонент, (внесенных на панель компонент), информа­ция об элементах, размещенных в этой секции, становится доступной через инспектор объектов.

Потомки класса могут менять область доступности всех эле­ментов родительского класса, кроме элементов, объявленных в секции private, так как последние им недоступны.

Все объекты Delphi являются динамическими, т. е. разме­щаемыми в динамической области памяти. Соответственно пе­ременная типа класса по смыслу представляет собой указатель на объект. Вызовы конструктора и деструктора являются обя­зательными, так как конструктор выполняет размещение объ­екта в памяти, а деструктор — выгрузку из нее.

Упражнение. Разработать класс, переменные которого используются для описания положения геометрической фигу­ры на экране.

Решение

Проектируемый класс должен содержать поля для сохране­ния положения элемента на экране — координаты местополо­жения х и у, при этом возможными действиями являются инициализация элемента, получение координат, разрушение объекта.

Определим класс Position:

Для хранения значений координат введем два поля Fx и Fy (в языке Object Pascal принято соглашение названия полей на­чинать с символа F (от слова Field — поле)). Это внутренние данные класса, чтобы обеспечить их целостность, опишем их в разделе private.

Constructor Create предназначен для создания экземпляра класса (объекта), а также для определения начальных значе­ний его полей.

Destructor Destroy предназначен для удаления объекта из динамической памяти.

Подчеркнем, выделим мысль о том, что согласно идеологии объектно-ориентированного программирования все действия с данными, определенными в классе, осуществляются только пу­тем использования методов объекта. Методы GetX и GetY по запросу обращаются к соответствующему полю объекта и воз­вращают координаты положения объекта.

Итак, объединение данных с действиями над этими данными порождает новый тип, а процесс называется инкапсуляцией.

Создавая объекты типа TPosition, инициализируя их в соот­ветствии с условием, получим разные положения на экране, причем параметры будут храниться внутри объектов.

Каждая переменная типа class включает набор полей, объяв­ленных в классе. Совокупность значений, содержащихся в этих полях, моделирует конкретное состояние объекта предметной области. Изменение этих значений в процессе работы отражает изменение состояния моделируемого объекта.

Воздействие на объект выполняется посредством изменения его полей или вызова его методов. Доступ к полям и методам объекта осуществляется, за исключением специальных случаев, с указани­ем имени объекта (при этом используются составные имена):

<�имя_объекта>.<�имя_поля>; ИЛИ

<�имя_объекта>.<�имя_метода>;

Все методы объекта обязательно имеют доступ ко всем по­лям своего объекта. В языке Object Pascal это достигается через неявную передачу в метод специального параметра Self — адре­са области данных конкретного объекта. Таким образом, уме­ньшается количество параметров, явно передаваемых в метод.

</0></0></0>
1   2   3   4   5   6   7   8

Похожие:

Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций междисциплинарного курса мдк. 03. 01 Технология разработки...
Исследовать процессы создания новых технологий и определять их основные тенденции целесообразно, сопоставляя эти технологии с уровнем...
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций междисциплинарного курса мдк. 03. 01 Технология разработки...
Исследовать процессы создания новых технологий и определять их основные тенденции целесообразно, сопоставляя эти технологии с уровнем...
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Методические рекомендации по выполнению внеаудиторной самостоятельной...
ПМ. 01 Разработка программных модулей программного обеспечения для компьютерных систем
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций
Ш 39 Метрология, стандартизация, сертификация: Конспект лекций / О. А. Шейфель; Кемеровский технологический институт пищевой промышленности....
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций для студентов всех форм обучения специальности 080110...
Налоги и налогообложение: Конспект лекций / Составитель Н. А. Леончик. – Кемерово, 2006. – 80 с
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Календарно-тематический план учебной дисциплины преподаватель Алексеев Александр Игоревич
Наименование междисциплинарного курса мдк. 01. 01 Электрические машины и аппараты
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Технические средства автоматизации конспект лекций
Конспект лекций предназначен для студентов дневной, вечерней, заочной и дистанционной форм обучения по специальности 220301 «Автоматизация...
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций мдк 02. 02. Электронные средства и методы геодезических измерений
ПМ. 02. Выполнение топографических съемок, графического и цифрового оформления их результатов
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций Владимир 2010 Министерство образования Российской...
Автоматизированные системы бухгалтерского и управленческого учета. Часть 1: Конспект лекций / Владим гос ун-т; Сост.: Д. Н. Васильев...
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций лаконично раскрывает содержание и структуру учебной...
Безопасность жизнедеятельности : конспект лекций для студентов очной и заочной форм обучения / сост. В. М. Домашко; Южный федеральный...
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций содержание тема Предмет и задачи курса
Внутренняя и внешняя среда организации (фирмы) и их взаимосвязь. Мировой рынок и его развитие
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Рабочая программа спецкурса Олимпиадное программирование 8 и класс...
Рабочая программа элективного курса «Олимпиадное программирование» для 8 специализированного класса инженерно-технологической направленности...
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Рабочая программа междисциплинарного курса мдк 01. 06 «Постановка голоса, хор»
ПО) по программам подготовки специалистов среднего звена (далее – ппссз) по специальности 53. 02. 03 Инструментальное исполнительство...
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Рабочая программа междисциплинарного курса «Средства исполнения дизайн-проектов»
Рабочая программа междисциплинарного курса «Средства исполнения дизайн-проектов» разработана на основе Федерального государственного...
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций по дисциплине для специальности 080101. 65 «Экономическая безопасность»
Информационные системы в экономике: конспект лекций по дисциплине для обучающихся по специальности 080101. 65 «Экономическая безопасность»...
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций по дисциплине «Научные основы производства продуктов питания»
Конспект лекций по дисциплине «Научные основы производства продуктов питания» для студентов кафедры «Технология и организация общественного...

Руководство, инструкция по применению




При копировании материала укажите ссылку © 2024
контакты
rykovodstvo.ru
Поиск