Программирование на языке Object Pascal

Элементы языка Object Pascal: идентификаторы, константы, переменные, выражения. Структура проекта Delphi. Операторы и метки. Типы данных языка OPascal. Статические и динамические массивы. Записи с вариантными полями. Совместимость и преобразование типов.

Рубрика Программирование, компьютеры и кибернетика
Вид курс лекций
Язык русский
Дата добавления 18.02.2012
Размер файла 385,4 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

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

В OPascal строка выглядит как цепочка символов, к каждому символу можно обратиться как к элементу одномерного массива указав его индекс:

s: “это_строка”;

s1:=s6; [т]

Строка хранится в памяти компьютера следующим образом - самый первый элемент строки имеет индекс 0 и содержит значение текущей длинны строки:

10 ( это_строка ) - для человека

A (ASCII код символов) - для компьютера

Над длинной строки можно производить необходимые действия оперируя с нулевым байтом строки.

Над строками допустимы следующие операции:

1). Сравнение (результат - истина, если строки идентичны).

2). Сложение.

S1:= “ab”;

S2:= “12”

S3:=s1+s2; [“ab12”]

При записи строки допустимо использовать ASCII коды символов:

S:= “abs”;

S:= #65#66#67;

S:= “a”#66 “c”

Если, при сцепление строк, длинна строки более 255 символов, то лишние символы отсекаются.

Правила сравнения строк:

<,> - допустимо использование при работе со строками. Строки сравниваются поэлементно в соответствие с их ASCII кодами. Если коды соответствующих символов строк отличаются от операций < или > выдают истина или ложь.

s1:= “abcde”; [65 66 67 68 69]

s2:= “abcae”; [65 66 67 65 69]

s1>S2

s1:= “abc”; [65 66 67]

s2:= “abcde”; [65 66 67 68 69]

s2>S1

Процедуры и функции для работы со строками:

Concat (s1, s2 … sn): string; - сцепление строк в списке параметра, возвращает результат функция string;

Copy (st, index, count): string; - возвращает из st count символов:

s1:= “конкатспация”;

s2:= copy (s1, 4, 3); [“кат”]

Delete (st, index, count): string; - удаляет из строки st с позиции index count символов:

s1:= “процедура”;

s2:= delete (s1, 1, 5); [“дура”]

Insert (s1, st, index); - возвращает в строку s1 строку st начиная с позиции index:

s:= “дверь”;

s2:= “е”;

s3:=insert (s, s2, 2); [“деверь”]

Length (s): byte - возвращает начальную длину строки.

Pos (s1, s): byte - возвращает позицию первого вхождения подстроки s в s1:

s1:= “колокол”;

s:= “ол”;

s3:= pos(s1;s) [2]

Если подстрока s1 отсутствует внутри строки s, то pos возвращает (0).

Comparestr (s1,s2): Boolean; - сравнивает 2 строки с учетом регистра:

Comparestr (“Abc”; “abc”) [false]

Comparetext (s1,s2): Boolean - сравнивает 2 строки без учета регистра:

Comparetext (“Abc”; “abc”) [true]

Stingofchar (s,count): string - возвращает строку с повторяющимся количеством повторяющихся символов:

Stingofchar (`f',5); [fffff]

Sting replace (s1, s2, s3) - возвращает строку с заменой вхождений одной подстроки в другую. (s1 - в какой?, s2- что?, s3 - на что?)

Trim (строка): string - удаляет из строки пробелы и управляющие символы находящиеся в начале и в конце строки.

TrimLeft (строка): string - удаляет из строки пробелы и управляющие символы находящиеся слева в строке.

TrimRight (строка): string - удаляет из строки пробелы и управляющие символы находящиеся справа в строке.

Str (x, s); - эта процедура преобразует целое или вещественное число (x) к строковому формату и сохраняет результат в (s):

Var

X: real;

S: string;

Begin

X:= 230.561;

Str (x, s);

S:= s+ `a'; [`230.561a']

Val (s, x, c) - процедура преобразует строку (s) во внутреннее представление целой или вещественной переменной (x). Параметр (c) после завершения работы процедуры содержит (0), если преобразование прошло успешно, или содержит номер позиции в которой произошла ошибка:

Var

C: integer;

X: real;

S: string;

Begin

S:= `232';

Val (s, x, c); (x = 2.32 E + 2; c = 0.)

S:= `58*2';

Val (s, x, c); (x = 5.8 E + 1; c = 3.)

StrToInt (string): integer - преобразует строку в целое число.

StrToFloat (string): extended - преобразует число в строку.

StrToDatetime

IntToStr

Floattostr

StrToIntDef (string, integer) - переводит строку в целое число, при ошибке выдает число по умолчанию.

TryStrToInt (string): Boolean - попытка перевести число в строку.

IV. Процедуры.

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

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

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

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

Локализация имен

Все подпрограммы, вызываемые в модуле, должны быть предварительно объявлены:

· Либо упоминанием заголовка в интерфейсном разделе;

· Либо полным описанием в разделе реализации своего модуля.

Каждая подпрограмма имеет структуру, схожую со структурой основной программы, модуля и проекта:

Procedure/Function имя [(параметры)] [<тип, результаты и другие функции>]

Type

<объявление типов>;

Const

<объявление констант>;

Var

<объявление переменной>;

Label

<объявление меток>;

Begin

<тело подпрограммы>;

End;

Процедура выполняет только тело подпрограммы, а функция возвращает еще и значение результата.

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

Пример:

Unit Primer;

.

.

Var V1…;

.

.

Implementation

Procedure A

Var V2;

Begin;

End;

Procedure B;

Var V3

Procedure B1;

Var V4;

Procedure B2;

Var V5;

Begin;

.

.

Begin;

.

.

End;

Begin

.

.

End;

End;

End.

Из процедуры (B2) доступны переменные (V1, V3, V4, V5).

Из процедуры (V1) доступны переменные (V1, V3, V4).

Из процедуры (B) доступны переменные (V1, V3).

Из процедуры (A) доступны переменные (V1, V2).

На уровне модуля доступна переменная (V1).

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

Пример:

Procedure A;

Var;

s: string;

Procedure B;

Var

s: string;

Begin

s: `bbb!';

Label1; Caption:= `внутри процедуры B s='+s;

End;

Begin

s: `aaa';

Label0; Caption:= `до выбора в процедуре B s='+s;

End;

Label0 [`до входа ... ааа']

Label1 [`внутри процедуры ... bbb!']

Label2 [после процедуры ... ааа]

Из внутренней процедуры можно обратиться к одинаковому идентификатору внешней, с помощью спецификатора:

pascal идентификатор константа массив

<имя процедуры. Имя идентификатора.> A.S.

.

.

s: `bbb!'

label1. Caption: `внутри процедуры B s=' + s + `а внутри процедуры A s=' + A.S.;

.

.

При взаимодействие подпрограмм одного и того же уровня иерархии вступает в действие следующее правило:

Любая подпрограмма перед ее использованием должна быть объявлена.

Пример:

Unit Primer

Interfeise

Procedure C; [или A, B]

Procedure A;

Procedure B;

Implementation

Procedure A;

Begin

.

.

End;

Procedure B

Begin

. [A];

.

End;

Procedure C;

Begin

. [A, B];

.

End;

End.

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

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

Формальные и фактические параметры

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

Пример:

Procedure A;

Var

a, b: real;

Function Add (x, y: real;): real; (x, y - формальные параметры)

Begin

Add:= x + y;

End;

Begin

a:=3

b:= Add(a,11); [14] (Add - фактический параметр)

End;

Синтаксис записи процедур и функций

Procedure <имя> [([var] <имя> : <тип>; [[var] <имя1, имя2…> : <тип1 …>])];

Function <имя> [([var] <имя1> : <тип1>, [var] <имя2, имя3…> : <тип3>)] : <тип результата>

Функция в отличие от процедуры обязательно возвращает значение указанного типа и может использоваться только в выражение.

В теле функции (Begin … End;) обязательно должна присутствовать следующая строка:

имя функции := ...;

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

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

Function Sum (n: integer): integer;

Var

i, s: integer;

Begin

S:= 0;

For i = 1 to n do s:= s + i;

Sum:= s;

End;

Function Sum (n: integer): integer;

Var

i: integer;

Begin

Result:= 0;

For i = 1 to n do result:= result + i;

End;

Способы передачи параметров подпрограммы:

· Передача по ссылке (в подпрограмму передается ссылка(адрес фактического параметра));

· Передача по значению (в качестве параметра передается копия значения фактического параметра);

· Передача по названию (подпрограмме передается имя той переменной, которая является фактической переменной (в современных языках программирования этот способ не применяется)).

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

Параметры, передаваемые по значению, внутри подпрограммы изменить нельзя.

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

Пример:

Procedure ABC;

Var

x, y: integer;

Procedure Test (p1: integer; var p2: integer);

Begin

P1:= p1 + 1, p2:= p2 + 1;

Label1. Caption:= `p1=' + IntToStr(p1); [p1 = 2]

Label2. Caption:= `p2=' + IntToStr(p2); [p2 = 6]

End;

Begin

x:=1, y:= 5;

Test (x, y);

Label3. Caption:= `x=' + IntToStr(x); [x = 1]

Label4. Caption:= `y=' + IntToStr(y); [y = 6]

End;

Комментарий к подпрограмме: В данном примере в процедуру Test передается два параметра (p1, p2): (p1 - по значению, p2 - по ссылке), соответствующие им фактические параметры x и y, после выхода из процедуры Test, принимают следующие значения: (x = 1, т.е. остается неизмененной, т.к. в процедуре изменялась лишь его копия; y - меняет свое значение, т.к. в процедуру был передан его адрес и изменения производились по этому адресу).

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

Механизм работы подпрограмм

Использование аппаратного стека.

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

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

Элемент, занесенный в аппаратный стек последним - верхушка стека.

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

Программы ПВЭМ строятся по сегментному принципу.

Сегмент - участок памяти размером 64 Кбайт, адрес любой ячейки равен адресу ячейки + адрес смещения.

Сегменты бывают трех типов:

· (CS) кода - есть всегда;

· (DS или ES) занятый - если ячейка занята данными;

· (SS) стека - если используется процесс или константа (параметр, переменные, адрес возврата).

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

При вызове подпрограммы в аппаратный стек заносятся:

· Фактические параметры (в том порядке, в котором они указанны);

· Адрес возврата;

· Блок локальных переменных.

Занесение в стек происходит именно в таком порядке.

Пример:

Var

x, y: integer;

Implementation

Procedure Two (p1, p2);

Var

y, z: integer;

Procedure Three (p);

Var

z, a: integer;

Begin

Two (z, p); [@M4]

End;

Procedure Four;

Var

y, a: integer;

Begin

Three (y); [@M3]

End;

Begin (Two)

Four [@M2]

End;

Procedure Batton1. Click (...)

Begin

Two (x, y); (@M1)

End;

End.

По завершении работы программы происходит извлечение из аппаратного стека в обратном порядке.

Указатели

Указатели и динамическая память.

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

Динамическая память основана на работе с адресами. При динамическом выделении памяти, заранее не известно: не тип, не количество размещаемых данных. В динамической памяти нельзя обращаться по именам, а только по адресам.

Адреса и указатели

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

Указатель - переменная, которая в качестве своего значения содержит адрес байта памяти:

p: pointer; [@]

В ПЭВМ адреса задаются совокупностью двух шестнадцатеричных слов:

1. первое слово - сегмент;

2. второе слово - смещение.

Структура адреса ячейки на примере 20-и разрядной адресации:

Объявление указателей

Существует два типа указателей:

1. типизированные (связываются с некоторым типом данных);

2. не типизированные (просто хранят адрес определенного участка памяти). Указатели объявляются в разделе описания переменных и в разделе описания типов (Type и Var).

Объявление типизированных указателей.

имя: ^название типа;

Var

p1: ^integer;

p2: ^real;

...

Type

PersonPainter=^PersonRecord;

PersonRecord=Record;

name: string [20];

age: byte;

next: PersonPeinter;

End;

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

Объявление не типизированных указателей.

имя: painter;

Var

p: painter;

p1,p2: ^byte; [1 байт]

p3,p4: ^real; [8 байт]

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

Var

p: painter;

p1,p2: ^byte;

p3,p4: ^real;

...

p1:=p2;

p3:=p4;

p1:=p3;

p4:=p2;

p1:=p1;

p3:=p;

Обнуление указателя

p:=Nil; - после выполнения этой операции указатель продолжает занимать место в памяти, но указывает в никуда (т.е. ни на одну ячейку).

p:=Nil;

Выделение и высвобождение динамической памяти

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

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

1. HeapOrg - хранит адрес начала кучи;

2. HeapEnd - хранит адрес конца кучи;

3. HeapPTR - хранит адрес начала незанятого участка кучи.

Выделение в памяти для типизированных указателей осуществляется с помощью процедуры New (имя указателя):

Var

p: ^byte;

Begin

1 New(p);

2 p^:=2;

1. Администратор кучи просматривает ее содержимое и если есть свободный байт - выделяет его, а адрес этого байта записывается в переменную (p).

2. Запись числа (2) в свободное место с адресом (p).

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

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

Разадресованные указатели могут использоваться в любых выражениях и операциях:

Var

p:^byte;

x:real;

Begin

New(p);

p^:=2;

x:=SQRT(p^)+2*p^/3

Высвобождение динамической памяти.

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

Dispose(p);

После процедуры dispose указателю снова можно выделить память.

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

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

Для не типизированных указателей выделение памяти осуществляется процедурой: GetMem (имя указателя, размер). Размер - количество байт, которые будут помечены как занятые. Он может быть от 1 до 65535 байт.

Высвобождение памяти для не типизированных указателей:

FreeMem (имя указателя, размер);

Пример:

Var

p: pointer;

Begin

GetMem (p,400);

FreeMem (p,400);

Процедуры для высвобождения динамической памяти:

Mark (p) - запоминает адрес указателя (p);

Release (p) - высвобождает динамическую память начиная от адреса хранящегося в (p) до конца кучи.

Эти процедуры могут применяться к типизированным и не типизированным указателям.

Пример:

Var

p1, p2, p3, p4, p5: ^integer;

Begin

New (p1);

New (p2);

New (p3);

New (p4);

New (p5);

Процедуры и функции для работы с динамической памятью:

Addr(x): pointer; - функция возвращает результат типа pointer в котором содержится адрес аргумента (x), где (x) - любой объект программы (переменная, массив, объект указателя);

CSeg: word; - (возвращает значение хранящееся в регистре CS) в начале работы программы в регистре программы (CS) хранится сегмент кода;

DSeg: word; - (возвращает значение регистра DS) в начале работы программы в регистре (DS) хранится сегмент данных;

MaxAvail: int64; - (возвращает в байтах размер наибольшего непрерывного участка кучи);

MemAvail: int64; - (возвращает в байтах размер общего свободного пространства кучи);

Ofs(x): word; - (возвращает значение смещения адреса для указанного объекта (x)) (x) - выражение любого типа или имя процедуры;

Seg(x): word; - (возвращает значение содержащее сегмент адреса указанного объекта);

PTR(s, o: word): pointer; - (s - сегмент, o - смещение) возвращает значение типа pointer по заданному сегменту (s) и смещению (o).

Динамические структуры памяти

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

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

Список - линейная структура данных, с помощью которой задаются одномерные отношения.

Структуры элемента одномерного списка

Однонаправленный список:

Двунаправленный список:

Порядок расположения информационных и ссылочных полей в элементе произволен.

Информационная часть может содержать поля различных типов.

Ссылки должны быть однотипны.

В зависимости от числа ссылок список бывает однонаправленный и двунаправленный.

Линейный однонаправленный список:

First - голова списка.

Список называется пустым, если указатель на первый элемент равен Nil: First=Nil;

Линейный двунаправленный список:

First - голова списка.

Last - хвост списка.

Так же существуют кольцевые списки, у которых последний элемент указывает на первый.

Пример Описание элемента однонаправленного списка:

Type Type

point=^zap; point=^zap;

zap=record; zap=record;

int1: integer; int1: integer;

int2: string; int2: string;

next: EL; next: point;

End; prev: point;

End;

Все действия над элементами списка (вставка, удаление, перестановка) сводятся к действиям со ссылками. Сами элементы при этом своего физического положения в памяти не меняют.

Задачи для работы с линейным списком.

1_Создание пустого списка:

Procedure Create_Empty_List (var first: EL);

Begin

First:= nil;

End;

2_Добавление элемента в список:

Procedure Create_New_Elem (var p: EL);

Begin

New (p);

p^: inf1:= StrToInt (Edit1.text);

p^: inf2:= Edit2.text;

p^: next:= nil;

End;

Create_Empty_List (first);

Create_New_Elem (p1);

first:= p1;

Create_New_Elem (p2);

p1^.next:=p2

3_Подсчет количества элементов в списке:

Function Count_El (first: EL): integer;

Var

k: integer;

q: EL;

Begin

If first=nil then k:=0

Else

Begin

k:=1;

q:= first;

While q^.next <> nil do

begin

k:=k+1;

q:=q*next;

end;

End;

End;

Result:= k;

End;

Аналогично записывается процедура: 1. вывода списка на экран;

2. поиск внутри списка…

4_Вставка элемента в начало списка:

Procedure ins_Bea_List (p: EL; var first: EL);

Begin

If first=nil then

Begin

first:= p;

p^.next:= nil;

End;

Else

Begin

p^.next:=first;

first:=p;

End;

End;

5_Добавление элемента в конец списка:

Procedure ins_End_List (p: EL; var first: EL);

Var

q: EL;

Begin

If first=nil then

Begin

first:=p;

p^.next:=nil;

End;

Else

Begin

q:=first;

While q^.next<>nil do

q=q^.next;

q^.next:=p;

p^.next:=nil;

End;

End;

6_Добавление элемента в середину списка (после i-того элемента):

Procedure ins_After_i (p: EL; first: EL; i: integer);

Var

t,q: EL;

k,n: integer;

Begin

n:= Count_EL (first);

if (i<1) or (i>n) then

Begin;

ShowMessage (`i, задано не корректно');

Exit;

End;

Else

Begin

If i=1 then

Begin

t:=first;

q:=t^.next;

t^.next:=p;

p^.next:=q;

End;

Else

If i=n then

first:=p;

Else

Begin

q:=first;

While q^.next<>nil do

q:=q^.next;

q^.next:=p;

End;

End;

Else

Begin

t:=first;

k:=1;

While k<i do

Begin

k:=k+1;

t:=t^.next;

End;

q:=t^.next; //в t:=i, a в q:=i+1

t^.next:=p;

p^.next:=q;

End;

End;

7_Удаление первого элемента в списке:

Procedure Del_Beg_List (var first: EL);

Var

p: EL;

Begin

If first<>nil then

Begin

p:=first;

if p^.next=nil then

Begin

Dispose(p);

First:=nil;

End;

Else

Begin

p:=first;

first:=first^.next;

Dispose(p);

End;

End;

End;

8_Удаление последнего элемента в списке:

Procedure Del_End_List (var first: EL);

Var

t,g: EL;

Begin

If first=nil then exit;

If first^.next=nil then

Begin

t:=first;

Dispose(t);

first:=nil;

End;

Else

Begin

q:=first;

t:=first;

While q^.next<>nil do

Begin

t:=q;

q:=q^.next;

End;

// t - предпоследний, q - последний.

Dispose (q);

t^.next:=nil;

End;

End;

9_Удаление i-того элемента из середины списка:

Procedure Del (var first: EL; i: integer);

Var

t, q: EL;

k, n: integer;

Begin

If first=nil then exit;

n:=count_EL(first);

if (i<1) or (i>n) then

Begin

ShowMessage(`I задано не корректно');

Exit;

End;

If i=1 then

Begin

// удаление первого элемента в списке (процедура выше)

End;

Else

If i=n then

Begin

// удаление последнего элемента в списке (процедура выше)

End;

Else

Begin

t:= first;

q:= nil;

k:=1;

While k<I do

Begin

k:=k+1;

q:=t;

t:=t^.next;

End;

k:=t^.next; //(i-1):=q, (i):=t, (i+1):=k

q^.next:=k;

Dispose(t);

End;

End;

10_Удаление всего списка:

Procedure Del_List (var first: EL);

Var

p; q: EL;

Begin

If first=nil then exit;

q:=first;

p:=nil;

While q<>nil do

Begin

p:=q;

q:=q^.next;

Dispose(p);

End;

first:=nil;

End;

Кроме линейных структур, с помощью указателей можно реализовать не линейные структуры (деревья).

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

np: ^node;

node=record;

inf: string;

left: np;

right: np;

end;

Графика в Delphi

Delphi позволяет использовать графические возможности операционной системы Windows. В операционной системе Windows графические возможности предоставляет графический интерфейс Win32. в частности интерфейс известный как GDI. Интерфейс GDI используется в системе Win32 для рисования и раскраски изображений. До появления Delphi для программирования графики в среде Windows необходимо было напрямую работать с функциями и процедурами GDI. В Delphi существует объект TCanvas (холст), который инкапсулирует и упрощает использование функций и инструментов (методов) GDI.

Представление рисунка в Delphi

TImage - компонент с таким же названием доступен на палитре компонентов Inditional. С помощью компонента TImage можно загрузить и отобразить на экране любой рисованный файл (*.bmp, *.wmf (16-и разрядный метафайл Windows), *.emf (32-х разрядный расширенный формат метафайла), *.ico, *.jpeg, а так же файлы других графических форматов поддерживаемых надстройками класса TGraphic).

Графические данные хранятся в свойстве picture объекта TImage.Picture.

Определение размеров графического файла:

1. размер (количество пикселей) Ч координата (x) Ч координата (y);

2. размер (длинна по (x)) Ч размер (длинна по (y)) Ч количество пикселей Ч цвет.

Растровая графика

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

Основной недостаток - плохая масштабируемость (Paint, Photoshop…).

Векторная графика.

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

Delphi работает только с растровой графикой.

Существует два типа растров:

1). Зависимые от устройства (DDB);

2). Не зависимые от устройства (DIB).

Delphi работает только с независимыми от устройств растрами, т.к. они работают со всеми устройствами.

Загрузка изображения на форму.

Сохранение изображения.

Для этого используется класс TPicture. Он представляет собой контейнерный класс для инкапсуляции абстрактного класса TGraphic.

Контейнерный означает, что класс TPicture может хранить ссылки на объекты: TBitmap, TMetafile, TIcon.

Пример Изображение на форме какой-либо картинки:

Procedure TForm1.Button1.Click (sender: object);

Begin

Imege1.Picture.LoadFromFile (`c:\*.bmp');

End;

Для сохранения используется метод SaveToFile:

Image1.Picture.SaveToFile (`c:\*.bmp');

Для работы с файлами формата JPEG необходимо в строке используемых модулей записать модуль JPEG.

Класс TBitmap

Класс TBitmap предназначен для хранения растрового изображения. Он инкапсулирует объект растров и палитры системы Win32.GPI.

Создание объекта:

Var

b: TBitmap;

Procedure …

Begin

b:=TBitmap.Create;

b:=nil // или b.Destray;

End;

Методы объекта TBitmap:

1. .LoadFromFile - загрузить в объект;

2. .SaveToFile - сохранить;

3. .Assign - позволяет скопировать один растр в другой.

Var

b1, b2: TBitmap;

Begin

b1:= TBitmap.Create;

b2:= TBitmap.Create;

b1.LoadFromFile(…);

b2.Assign(b1);

End;

При использование метода *.Assign копирование происходит следующим образом: в объект (b2) записывается ссылка на объект (b1), что позволяет сэкономить память; в случае внесения изменений в объект (b2) происходит автоматическое копирование объекта (b1).

4. .CopyRect - позволяет скопировать прямоугольную часть растрового изображения из одного объекта Bitmap в другой или на форму.

Типы данных в OPascal:

TPaint - точка;

TRect - прямоугольник;

Пример:

Var

a: TPaint;

b: TRect;

a.x:=100;

a.y:=150;

b.left:=10;

b.top:=10;

b.right:=100;

b.botton:=100;

Пример Нарисовать прямоугольник:

Var

r1: TRect;

Begin

r1.top:=0; // левая

r1.left:=0; //верхняя

r.night:=90; //правая

r.botton:=90; //нижняя

Bitmap1.Convas.CopyRect (ClientRect, Bitmap2.Canvas, r1);

End;

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

Пример:

Var

R1: TRect;

Bitmap1: TBitmap;

Begin

Bitmap1:=TBitmap.Create;

Bitmap1.LoadFromFile(`c:\picture1.bmp');

R1.left:=0;

R1.top;=0;

R1.right:=Bitmap1.Width;

R1.botton:=Bitmap1. Leight;

Form1.Canvas.StretchDrow (r1, Bitmap1);

End;

Использование свойств класса TCanvas:

1. TPen - перо (объект отвечает за способ и цвет рисования линий на канве): Image1.Canvas.Pen.

Свойства объекта TPen:

Цвет (color):

With Image1.Convas.Pen.Color do

Begin

Color:=clRed;

End;

Или выбор цвета случайным образом

Color:=RGB(random (256), random (256), random (256));

Тип линии (style):

.Style:=psSolid;

Виды линий:

psSolid - сплошная;

psDash - пунктир;

psDashDot - точка / пунктир;

psDashDotDot - пунктир / точка / точка

psDod - точки;

psClear - бесцветная.

Pen.Mode - режим работы пера (задает способ изображения линии на канве; способ смешения цветов при накладывание объектов).

Режим работы пера задается логическими операциями (pnCopy - по умолчанию).

2. TBrush - кисть (обладает тремя основными свойствами: color, style, bitmap):

Свойства объекта TBrush:

Цвет (color):

With Image1.Convas.Brush.Color do

Begin

Color:=clRed;

End;

Или выбор цвета случайным образом

Color:=RGB(random (256), random (256), random (256));

Тип линии (style):

.Style:=psSolid;

Виды линий:

bsSolid - сплошная;

bsBDiagonal - снизу вверх;

bsFDiagonal - сверху вниз;

bsDiagCross - решетка по диагонали;

bsCross - решетка;

bsHorizontal - горизонтальные линии;

bsVertical - вертикальные линии;

bsClear - бесцветная.

bitmap (позволяет закрашивать область, заданным из реестра цветом):

Bitmap1.loadFromFile(`...');

Image1.Convas.Brush.Bitmap:=Bitmap1;

Основные методы объекта Canvas:

Canvas.MoveTo(a: TPaint); - перемещает (но не рисует) перо в указаннуюточку;

Canvas.LineTo(a: TPaint); - рисует линию от текущего указателя пера до точки (a);

Canvas.Rectangle (a: TRect); - рисует прямоугольник;

Canvas.Rectangle (a1:TPaint; a2:TPaint); - рисует прямоугольник;

Canvas.Ellipse (e: TRect); - рисует овал вписанный в прямоугольник;

Canvas.Arc (e: TRect); - рисует дугу;

Canvas.FillRect (a: TRect); - рисует прямоугольник текущим пером и закрашивает его текущей кистью;

Canvas.FloodFill (x, y: integer; c: TColor; f {fsSurfase, fsBorder})

f - способ заливки;

fsSurfase - залить вся область, где цвет равен цвету указанному в третьем параметре;

fsBorder - залить вся область, где цвет не равен цвету указанному в третьем параметре.

Canvas.TextOut (x, y: integer; s: TString); - выводит в указанном месте текст на канву; шрифт задается при помощи Convas.Front.

Объект Screen (экран).

Этот объект существует всегда, вне зависимости от других объектов. Объект так же может использоваться для графики.

Размещено на Allbest.ru


Подобные документы

  • Основные понятия и структура обработчика на языке Pascal. Элективные курсы по информатике в системе профильного обучения. Элективный курс "Программирование в среде Delphi". Методические материалы по изучению программирования на языке Object Pascal.

    методичка [55,4 K], добавлен 08.12.2010

  • Характеристика вычислительной системы и инструментов разработки. Программирование на языке Pascal в среде Turbo Pascal и на языке Object Pascal в среде Delphi. Использование процедур, функций, массивов, бинарного поиска. Создание базы данных в виде файла.

    отчет по практике [2,1 M], добавлен 02.05.2014

  • Free Pascal как свободная реализация языка Паскаль, совместимая с Borland Pascal и Object Pascal - Delphi, но при этом обладающая и некоторыми дополнительными возможностями. Основы алгоритмизации и программирования, создание визуальных приложений.

    учебное пособие [4,2 M], добавлен 13.12.2011

  • Описание входной и выходной документации. Требования к интерфейсу Windows-приложения и информационной базе. Разработка алгоритмов обработки данных и SQL-запросов к базе данных. Язык программирования Object Pascal и среда Delphi. Используемая СУБД.

    дипломная работа [228,7 K], добавлен 25.11.2007

  • Разработка программы обработки типизированных файлов с кодом на языке Object Pascal, с использованием компонентов Delphi для ввода и вывода данных. Разработка экранных форм и алгоритма программы. Описание программных модулей и инструкция оператору.

    курсовая работа [1,5 M], добавлен 08.02.2011

  • Краткое описание работы базы данных. Программирование на языке Object Pascal в среде Delphi. Структура данных, описание типов и файлов. Глобальные и локальные переменные, процедуры, используемые в модуле. Расчёт объёма необходимой оперативной памяти.

    курсовая работа [215,7 K], добавлен 07.12.2010

  • Создание Windows-приложения на алгоритмическом языке Object Pascal в среде визуального программирования Delphi, которое, как планируется, будет обеспечивать решение специализированных задач по формированию, обработке на ЭВМ и выводу информации.

    курсовая работа [967,6 K], добавлен 20.05.2008

  • Информационные технологии и защиты данных. Методы защиты информации. Виды информационной безопасности и умышленные угрозы. Программирование на языке Turbo Pascal. Типы числовых данных. Функции ввода и вывода. Логические операторы, символьные переменные.

    курсовая работа [1,7 M], добавлен 16.05.2016

  • Запись в языке программирования – это структура данных, состоящая из фиксированного числа компонентов, называемых полями записи. Поле записи как обычная переменная. Операторы сравнения, присоединения. Программа с использованием массива структур.

    реферат [11,5 K], добавлен 19.01.2009

  • Особенности и тонкости программирования в среде Delphi. Специфика перехода от алгоритмического решения к непосредственной программной реализации на языке Object Pascal с использованием всех необходимых средств данного языка. Анализ полученных результатов.

    реферат [246,2 K], добавлен 17.11.2012

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.