Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
freePascal 2.0_0.doc
Скачиваний:
13
Добавлен:
01.05.2025
Размер:
343.55 Кб
Скачать

Оператор with.

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

Общий вид:

with переменная do оператор;

C использованием данного оператора к полям записи можно обращаться без указания префикса вместе с названием поля:

var pr1:person;

begin

with pr1 do

begin

FIO:=’Иванов’;

birth:=’1 января 1980 года’;

address.city:=’Шадринск’;

with address do

begin

street:=’Свердлова’;

house:=1;

end;

end;

end.

Вариантная запись.

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

Вариантная часть задается с помощью конструкции:

case имя поля of

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

type

family = (married, single);

person = record

FIO, birth : string ;

address : adr;

case yes: family of

married: (FIO1: string);

single: ()

end;

Важно:

  1. Любая запись (record) может иметь только одну вариантную часть (case).

  2. Вариантная часть должна помещаться после постоянной части.

  3. Среди идентификаторов полей не должно быть одинаковых.

Задача.

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

type

book=record

nazv,author:string;

year:integer;

end;

var b:array[1..100] of book;

i,n,g:integer;

begin

writeln(‘Введите количество книг’);

readln(n);

for i:=1 to n do

begin

with b[i] do

begin

writeln('Название ',i,' книги');

readln(nazv);

writeln('Автор ',i,' книги');

readln(author);

writeln('Год издания ',i,' книги');

readln(year);

end;

end;

writeln('Введите год издания');

readln(g);

for i:=1 to n do

if b[i].year=g then writeln(b[i].nazv);

readln;

end.

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

1. Ввести информацию об N людях (ФИО, Пол, Дата рождения, Место рождения). Определить:

1.1 Кто из них является самым молодым.

1.2 Посчитать количество мужчин и количество женщин.

1.3 Выяснить есть ли люди с одинаковым местом рождения. Если есть, то вывести их количество и место рождения.

2. Написать программу "Телефонный справочник". По введенной фамилии программа должна выдавать соответствующий номер телефона.

3. Определить победителя соревнований по силовому троеборью. В соревнованиях участвуют N участников. В протоколе указываются: фамилия, имя, отчество, вес спортсмена, результат по упражнениям № 1,2,3. Победителем считается спортсмен, набравший большую сумму баллов по результатам трех упражнений. При равенстве результатов побеждает спортсмен, чей вес оказался меньшим.

4. Определить количество дней в месяце. Для решения использовать запись, содержащую 2 поля: год, месяц. (Решить проблему високосного года).

Динамические структуры данных

Динамическая память

В языке программирования Free Pascal существует два способа выделения памяти под данные: статический и динамический.

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

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

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

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

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

Указатели

Указатель содержит адрес поля в динамической памяти, хранящего величину определенного типа. Сам указатель располагается в статической памяти.

Указатели делятся на стандартные и определяемые программистом. Величины стандартного типа – pointer, предназначены для хранения адресов данных произвольного типа:

var p : pointer;

Программист может определить указатель на данные или подпрограмму конкретного типа. Как и для других нестандартных типов, это делается в разделе type:

type pword = ^word; // указатель на word

var pw : pword;

Такие указатели называются типизированными. Можно описать указатель на любой тип данных, кроме файловых. Тип указателя на данные можно описать и непосредственно при описании переменной:

var pw : ^word;

Операции над указателями

Для указателей определены только операции проверки на равенство и неравенство и присваивания. Правила присваивания указателей:

  • Любому указателю можно присвоить стандартную константу nil, которая означает, что указатель не ссылается на какую-либо конкретную ячейку памяти.

  • Указатели стандартного типа pointer совместимы с указателями любого типа.

  • Указателю на конкретный тип данных можно присвоить только значение указателя того же или стандартного типа.

Операция @ позволяет получить адрес переменной:

var b : byte; // переменная

pb : ^byte; // указатель на величины типа byte

begin

pb := @b;

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

pb^ := 5;

writeln(pb^);

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

В языке программирования Free Pascal определен набор стандартных функций для работы с указателями:

addr(x) : pointer­ ‑ возвращает адрес х (аналогично операции @), где х — имя переменной или подпрограммы;

Assigned(p:pointer) : Boolean – возвращает True если указатель P не равен нулю и возвращает False если P нулевой.

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

Динамические переменные создаются в куче во время выполнения программы с помощью подпрограмм new или getmem. Динамические переменные не имеют собственных имен — к ним обращаются через указатели.

Процедура new(var p : тип указателя) выделяет в динамической памяти участок размера, достаточного для размещения переменной того типа, на который ссылается указатель p, и адрес начала этого участка заносит в этот указатель. Процедура new применяется для типизированных указателей.

Процедура getmem(var p : pointer; size : word) выделяет в динамической памяти участок размером в size байт и присваивает адрес его начала указателю p. Если выделить требуемый объем памяти не удалось, программа аварийно завершается. Указатель может быть любого типа.

Для освобождения динамической памяти используются процедуры Dispose и Freemem, причем, если память выделялась с помощью new, следует применять Dispose, в противном случае —Freemem.

Процедура Dispose(var p : pointer) освобождает участок памяти, выделенный для размещения динамической переменной процедурой или функцией New, и значение указателя p становится неопределенным.

Процедура Freemem (var p : pointer; size : word) освобождает участок памяти размеромsize, начиная с адреса, находящегося в p. Значение указателя становится неопределенным.

Если требуется освободить память из-под нескольких переменных одновременно, можно применять процедуры Mark и Release.

Динамические структуры данных

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

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

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

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

type

pnode = ^node;

node = record

d : word; // информационная

s : string; // часть

p : pnode; // указатель на следующий элемент

end;

Рассмотрим основные динамические структуры:

Линейные списки

В линейном списке каждый элемент связан со следующим и, возможно, с предыдущим. В первом случае список называется односвязным, во втором — двусвязным. Если последний элемент связать указателем с первым, получится кольцевой список.

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

Стек

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

Стек реализует принцип обслуживания LIFO (lastin — firstout, последним пришел — первым обслужен). Кстати, сегмент стека назван так именно, потому, что память под локальные переменные выделяется по принципу LIFO. Стеки широко применяются в системном программном обеспечении, компиляторах, в различных рекурсивных алгоритмах.

Очередь

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

Задача.

Создать программу для работы со стеком. Реализовать процедуры добавления элемента в стек (add), удаления элемента из стека (delete), вывод содержимого стека на экран (print).

type

pitem = ^item;

item = record

data: integer;

prev: pitem

end;

var

top, p: pitem;

n,i,ke,e,k,d: integer;

procedure add(x:integer);

begin

new(p);

p^.data := x;

p^.prev := top;

top := p

end;

procedure delete;

begin

if top<>nil then begin

p := top^.prev;

dispose(top);

top := p

end;

end;

procedure print;

begin

writeln('Стек:');

p := top;

while p <> nil do begin

write(p^.data, ' ');

p := p^.prev;

end;

writeln;

end;

begin

randomize;

top := nil;

writeln('Введите начальное количество элементов в стеке');

readln(ke);

for i := 1 to ke do

begin

k:=random(50);

add(k);

end;

d:=1;

while d<>0 do

begin

writeln('Выберите действие:');

writeln('1 – добавить элемент в стек');

writeln('2 – удалить N элементов стека');

writeln('3 – Вывести элементы на экран');

writeln('0 – выход');

readln(d);

case d of

1: begin writeln('Введите элемент');

readln(k); add(k); end;

2: begin writeln('Введите количество элементов

для удаления'); readln(ke);

for i:=1 to ke do

delete; end;

3: print

else if d<>0 then writeln(‘Ошибка ввода’);

end;

end;

readln;

end.

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

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

  2. *Создать односвязный список.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]