STR^- сама динамическая переменная;
STR^.elem - поле символьного значения (информационное поле);
STR^.sled - поле ссылки.
ПРИМЕР 7. Схема образования цепочки динамических данных
1. Зарезервировать место в памяти для указателей
2. Зарезервировать место в памяти для значений динамических переменных и поместить их адреса в указатели UKZV и UKSTR:
NEW(UKZV); NEW(UKSTR);
UKSTR | * | ® | UKZV | * | ® |
3. Заполнить поля ELEM значениями UKSTR^.ELEM:='P';
UKZV^.ELEM:='A':
UKSTR | * | ® | P | UKZV | * | ® | A |
4. Заполнить поля SLED значениями UKSTR^.SLED:=UKZV;
UKZV^.SLED:=NIL:
UKSTR | * | ® | P | * | ® | A | Nil |
Это пример построения цепочки из двух звеньев. Если же звеньев много, то все следует делать в цикле. Рассмотрим пример образования и распечатки цепочки, состоящей из последовательности букв и заканчивающейся ".".
Несколько предварительных соображений по данному примеру:
1) для ссылки на цепочку как единое целое введен указатель UKSTR;
2) для ссылки на очередное звено в цепочке введен указатель UKZV;
3) для продвижения по цепочке от одного звена к другому нужно текущему указателю UKZV присваивать в качестве значения ссылку на это следующее звено: UKZV:= UKZV^.SLED;
4) т.к. поле SLED имеет тип SVYAZ, т.е. ссылку на запись, то можно записать UKZV^.SLED^.SLED, что означает переход на звено, находящееся через звено от исходного;
5) при организации цепочки будем использовать "нулевое" (заглавное) звено, которое указывает на первое звено цепочки и не содержит никакого элемента. Так поступают для удобства обработки цепочки в цикле.
ПРИМЕР 8. Формирование и распечатка цепочки символов
program SOZDANIE_ZEPOCHKI;
type SVYAZ = ^ZVSTR;
ZVSTR = record
elem: char; sled: SVYAZ;
end;
var UKSTR, UKZV: SVYAZ; SYM: char;
begin { Создание головного (нулевого) звена }
¦ new(UKSTR); UKZV:= UKSTR; UKZV^.sled:= nil;
¦ read(SYM);
¦ { Создание всей цепочки}
¦ while SYM <> '.' do
¦ begin
¦ ¦ new(UKZV^.sled); UKZV:= UKZV^.sled;
¦ ¦ UKZV^.elem:= SYM; UKZV^.sled:= nil;
¦ ¦ read(SYM);
¦ end;
¦ UKZV:= UKSTR^.sled; writeln; {Печатьцепочки}
¦ while UKZV <> nil do
¦ begin
¦ ¦ write(UKZV^.elem,' ');
¦ ¦ UKZV:= UKZV^.sled;
¦ end;
end.
ПРИМЕР 9. Процедура удаления из списка SP элемента, содержащего в качестве данных некоторую букву
procedure UDALENIE_VNUTRI(var SP: SVYAZ; BUKVA: char);
var ZV: SVYAZ;
begin
¦ if SP = nil then writeln('Неттакогоэлемента!') else
¦ if SP^.elem <> BUKVA then UDALENIE(SP^.sled, BUKVA)
¦ else begin ZV:=SP; SP:=SP^.sled;
¦ dispose(ZV); end;
end.
ПОЯСНЕНИЕ. Данная процедура является рекурсивной. Выход из рекурсии осуществляется либо по нахождению и удалению соответствующей буквы, либо по достижению конца цепочки (обнаружение ссылки NIL). При удалении звена освобождается место в памяти с помощью DISPOSE.
Последний пример показывает, что для удаления одного элемента из цепочки достаточно применение одного оператора:
SP:= SP^.SLED.
И это действительно так, ибо устранение звена не есть его "физическое" уничтожение, а переброска ссылки на следующее звено, как это показано на схеме
SP | * | elem1 | * | elem2 | * | … | elemN | Nil |
ПРИМЕР 10. Процедура удаления первого элемента цепочки
procedure UDALENIE_NACHALO(var SP: SVYAZ);
var Q: SVYAZ;
begin
¦ if SP^.sled <> nil then
¦ begin
¦ ¦ Q:= SP;
¦ ¦ SP:= SP^.sled;
¦ ¦ dispose(Q);
¦ end
¦ else writeln('Списокпуст!');
end.
ПОЯСНЕНИЕ. Здесь введена вспомогательная переменная Q для временного хранения ссылки на удаляемое звено, прежде чем уничтожить его с помощью DISPOSE.
Вставка нового звена в цепочку занимает уже больше операций, т.к. для этого надо сделать две переброски: одну - из предыдущего звена на новое, вторую - из нового на следующее звено. Кроме того, необходимо образовать само это звено. Названные операции видны в следующей процедуре.
ПРИМЕР 11. Процедура вставки в список элемента, содержащего в качестве данных D, после элемента, содержащего X
procedure VSTAVKA_VNUTRI(var SP: SVYAZ; X, D: char);
var Q: SVYAZ;
begin
¦ if SP = nil then writeln('Неттакогоэлемента!')
¦ else if SP^.elem <> X then VSTAVKA(SP^.sled,X,D)
¦ else begin
¦ ¦ new(Q); Q^.elem:= D;
¦ ¦ Q^.sled:= SP^.sled; SP^.sled:= Q
end. end;
ПОЯСНЕНИЕ. Как и в примере 9, данная процедура является рекурсивной и по ней производится сначала поиск по цепочке звена, содержащего элемент Х, а затем сама вставка (если такое звено найдено).
ПРИМЕР 12. Процедура вставки звена в начало цепочки
procedure VSTAVKA_NACHALO(var SP: SVYAZ; D: char);
var Q: SVYAZ;
begin
new(Q); Q^.elem:= D;
Q^.sled:= SP^.sled;
SP^.sled:= Q
12. ПОНЯТИЕ ОБ ИНФОРМАЦИИ. ДАННЫЕ. СТРУКТУРЫ ДАННЫХ
Информатика - наука о способах сбора, хранения, переработки, передачи (распределения) и использования информации. Понятие "информация" является основным (базовым), и здесь можно говорить только о некоторых ее характерных чертах (сравните с понятием алгоритма, которое тоже не является определяемым).
В наиболее общем смысле информация есть неотъемлемое свойство взаимодействия систем. При любом взаимодействии систем всегда идет обмен информацией. Всякая система всегда погружена в какую-либо внешнюю информационную среду, получает из нее информацию, перерабатывает и выдает новую, которая, в свою очередь, может быть получена на входе какой-либо другой системы. Понятие системы может быть многозначным: человек, животное, робот, ЭВМ и пр.
В 40-х гг. XX в. ученый К.Шеннон попытался количественно описать информацию. Он ввел определение количества информации как меры определенности и упорядоченности. Шеннон считал, что с каждой порцией информации, полученной тем или иным объектом (системой), у объекта уменьшается неопределенность по какому-либо вопросу.
Под данными понимаются все объекты, с которыми оперирует информатика, в частности, вычислительная система, представленная комплексом аппаратных и программных средств. Вычислительные системы (или просто ЭВМ) работают под управлением программы, которую можно рассматривать как описание множества операций, применяемых к некоторым данным в некоторой последовательности. Данные, существующие во время выполнения программы, можно грубо разбить на два класса:
1. Данные программиста - он их определяет и ими манипулирует - простые данные, массивы, файлы и пр.
2. Данные системы - образуются для служебных целей во время выполнения программ - стеки точек возврата в процедурах, среда ссылок в динамических объектах, списки свободного пространства в памяти, сборка "мусора" и пр. Они создаются операционной системой без участия программиста.
В языках программирования существует большое разнообразие форм данных, которые может определить программист. Непосредственно с данными соприкасается понятие структуры данных, которое представляется как некоторая совокупность объектов, объединенных по какому-либо набору признаков и определенным образом связанных между собой.
Разные классы решаемых на ЭВМ задач характеризуются и разными структурами данных, что находит отражение и в соответствующих языках программирования. Каждый язык программирования ориентирован на определенный набор таких структур:
Структуры | Языки программирования | ||
данных | РАЯ | BASIC | PASCAL |
массивы | + | + | + |
литеры | + | + | + |
множества | - | - | + |
файлы | - | + | + |
списки | - | - | + |
Языки, ориентированные на решение различных классов задач, используют и различные способы представления и обработки структур данных. Однако следует заметить, что любая структура данных отображается на структуру машинной памяти, которая представляет собой линейную последовательность адресуемых ячеек (байтов).
Почти все вопросы, касающиеся данных, тесно переплетаются с операциями, при помощи которых данные обрабатываются. Одним из важных вопросов по работе с данными является доступ к элементам структуры. Некоторые типы данных доступны только целиком, например, числа, логические величины и указатели (ссылки), их называют простыми элементами данных. Другие типы данных разрешают доступ к частям элемента данных, например, массивы, списки, стеки и файлы. Они называются структурированными элементами данных.
Различие между простыми и структурированными элементами данных зависит от языка и типа разрешенных операций доступа. Например, цепочка литер в некоторых языках является простым элементом данных и доступна только целиком в операциях ввода - вывода и при передаче в подпрограммы (данные типа STRING в Паскале). В других же языках индивидуально доступна каждая подцепочка внутри цепочки литер, причем последняя является структурированным элементом данных (литерный массив).
По способу доступа принято выделять структурированные элементы данных трех типов:
1. Прямого доступа. Эта структура позволяет в любой момент времени получить доступ к любому элементу (массив, индексный файл).
2. Последовательного доступа. В этой структуре доступ к произвольному N-му элементу возможен только после перебора предыдущих N-1 элементов (цепочка, файл).
3. Древовидные структуры. Данные этой структуры следуют друг за другом, образуя при этом ответвления.