
- •Лекция 13. Динамические структуры данных
- •8.1. Указатели
- •8.1.1. Типизированные и нетипизированные указатели
- •8.1.3. Операции над указателями
- •8.1.4. Действия с указателями
- •8.1.5. Операторы для указателей (pointer)
- •8.2. Динамические переменные
- •8.2.1. Динамические структуры данных
- •8.2.2. Указатели и ссылки
- •8.2.3. Линейные списки. Основные операции
8.1.5. Операторы для указателей (pointer)
Операторы отношения <, >, <= и >= могут использовать операнды типа PChar. Следующие операторы также берут указатели как операнды.
оператор |
Операция |
Тип операндов |
Тип результата |
Пример |
+ |
Сложение указателей |
Указатель на символ, integer |
Указатель на символ |
P + I |
- |
Вычитание указателей |
Указатель на символ, integer |
Указатель на символ, integer |
P - Q |
^ |
Разыменовывание указателей |
Указатель |
Указатель на базовый тип |
P^ |
= |
Равенство |
Указатель |
Boolean |
P = Q |
<> |
Неравенство |
Указатель |
Boolean |
P <> Q |
Оператор ^ разыменовывает указатель. Операнд может быть указателем на любой тип кроме Pointer, который должен быть сначала приведен к конкретному типу прежде, чем его разыменовывать.
P = Q — True, если P и Q указывают на тот же адрес; в противном случае, P <> Q — True.
Можно использовать операторы + и – для увеличения или уменьшения сдвига указателя на символ. Операция – может быть использована для вычисления разности смещения двух символьных указателей. Для операций + и – выполняются следующие правила.
Если I — целое и P — символьный указатель, то P + I (Inc(P,I)) увеличивает на I адрес, определяемый P, т.е. возвращает указатель на адрес, смещенный на I символов после P. Выражение, которое I + P эквивалентно P + I. Операция P - I (Dec(P,I)) вычитает I от адреса, определяемого P, т.е. возвращает указатель на адрес, на I символов перед P.
Если P и Q — символьные указатели, то P - Q вычисляет число символов между P и Q.
8.2. Динамические переменные
Переменные, которые рассматривались до сих пор, являлись статическими. Это означает, что размер выделяемой для них памяти происходит при компиляции программы и остается неизменным во все время работы программы. Адрес (относительный) выделенной ячейки памяти определяется при компиляции и соотносится с именем переменной.
Такая структура данных, как массив, является удобным средством в тех случаях, когда необходим прямой доступ к его элементам. Однако, если необходимо, например, вставить новое значение в массив, то приходится сдвигать остальные элементы массива, как это делается при сортировке вставками. При удалении элемента из массива также приходится сдвигать остальные элементы. Если размерность массива N, и все его элементы определены, то вставка еще одного элемента вообще невозможна: память для статического массива также выделяется при компиляции. Файлы позволяют создавать последовательности элементов любой длины, однако файл – линейная структура, и доступ к дисковой памяти намного сложнее, чем к оперативной.
8.2.1. Динамические структуры данных
Многие задачи требуют более сложных, чем линейная, структур. Даже для линейных структур желательно иметь переменный размер и легкость вставки и удаления любого элемента структуры. Такие структуры изменяются во время выполнения программы, поэтому они называются динамическими.
Существуют некоторые близкие аналогии между методами структурирования алгоритмов и методами структурирования данных. Сравнение этих методов приведет нас к пониманию динамических структур и работы с ними.
Элементарным, неструктурированным оператором является оператор присваивания. Ему соответствует скалярный тип данных. Оба они являются простейшими строительными блоками для составных операторов и типов данных. Простейшие структуры, получаемые с помощью перечисления, или следования, – это составной оператор и запись. Оба состоят из небольшого количества компонент, которые могут различаться. Если все компоненты одинаковы, их не нужно выписывать отдельно: для того, чтобы описать повторения, число которых известно и конечно, пользуются оператором цикла с параметром (for) и массивом. Выбор из двух или более вариантов выражается операторами if или case и соответственно записью с вариантами. И, наконец, повторение неизвестное количество раз выражается оператором цикла с предусловием (while) или с постусловием (repeat). Соответствующая структура данных – последовательность (файл).
Оператор |
Структура |
:= |
Intger; real,… |
for |
array[1..N] of … |
While; repeat |
array of …; file of … |
If; case |
record … case … of |
Procedure; function - рекурсия |
? |
Существует ли структура данных, которая подобным же образом соответствует оператору процедуры? Разумеется, наиболее интересная и новая по сравнению с другими операторами особенность процедур – это возможность рекурсии. Значения типа данных, который можно назвать рекурсивным, должны содержать одну или более компонент того же типа, что и все значение, по аналогии с процедурой, содержащей один или более вызовов самой себя. Как и в процедурах, в таких определениях типов рекурсия может быть прямой или косвенной.