Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Указатели и ссылки

Читайте также:
  1. Библиографические ссылки
  2. БИБЛИОГРАФИЧЕСКИЕ ССЫЛКИ
  3. Библиографические указатели
  4. В представленном тексте, имеются ссылки на интернет страницы Радио «Вести FM», на которых можно не только прочесть, но и послушать указанные комментарии в полном объеме.
  5. Глава пятая. Побег из ссылки и от Яши
  6. Задание 5. Создание гиперссылки на существующую страницу или файл
  7. МЕСТО ПОЛИТИЧЕСКОЙ ССЫЛКИ

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

 

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

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

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

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

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

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

Элементарным, неструктурированным оператором является оператор присваивания. Ему соответствует скалярный тип данных. Оба они являются простейшими строительными блоками для составных операторов и типов данных. Простейшие структуры, получаемые с помощью перечисления, или следования, – это составной оператор и запись. Оба состоят из небольшого количества компонент, которые могут различаться. Если все компоненты одинаковы, их не нужно выписывать отдельно: для того, чтобы описать повторения, число которых известно и конечно, пользуются оператором цикла с параметром (for) и массивом. Выбор из двух или более вариантов выражается операторами if или case и соответственно записью с вариантами. И, наконец, повторение неизвестное количество раз выражается оператором цикла с предусловием (while) или с постусловием (repeat). Соответствующая структура данных – последовательность (файл).

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

Указатели и ссылки

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

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

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

type TPtr=^TElement.

Здесь имеется ввиду, что значениями типа TPtr являются ссылки на переменные типа TElement. Стрелка ^ читается как «ссылка на». Существенно, что тип элементов, на которые ссылаются значения типа TPtr, задан в его определении. Это означает, что TPtr связан с TElement. Эта связь отличает ссылки в языках высокого уровня от адресов в языке ассемблера и является очень важным средством увеличения надежности программ. Пусть есть описания

type Tp1=^TE1;

Tp2=^TE2;

var p1: Tp1;

p2: Tp2

Тогда переменные p1 и p2 – разных типов, так как они ссылаются на переменные разных типов. И это несмотря на то, что и размер памяти, отводимой под p1 и p2, – одинаков, и одинакова сущность их значений: обе эти переменные содержат адреса памяти.

Для работы с динамическими структурами необходимы следующие основные операции:

q создание переменной;

q удаление переменной.

Значения ссылочных типов создаются всякий раз, когда динамически создается соответствующая переменная. Для динамического создания переменной служит стандартная процедура new. Если дана ссылочная переменная p типа TPtr, то оператор new(p) выделяет память для переменой типа TElement, создает ссылку типа TPtr на эту вновь созданную переменную и присваивает значение этой ссылки (адрес новой переменной) p. Поскольку собственно значение адреса программиста, как правило, не интересует, ссылка на переменную обозначается стрелкой.

 

Рис. 8.1.

Сама ссылкаобозначается как p, значение ее – адрес динамически созданной переменной. Динамически созданная переменная своего имени не имеет, но к ней можно обратиться через ее ссылку, и тогда p^ – динамически созданная переменная.

К множеству значений типа TPtr добавляется еще одно значение – Nil, (от англ. ничего, ноль) которое не ссылается ни на какой элемент. Элемент, содержащий такое значение, является конечным элементом структуры.

Операции, допустимые над ссылочными переменными:

q Присваивание (p:=q). Как и для переменных других типов данных, присваивать одной ссылочной переменной можно значение другой ссылочной переменной только если эти переменные одного и того же типа. Значение Nil можно присваивать любой ссылочной переменной.

q Сравнение (if (p<>Nil) and (p=q) then …). Две переменные ссылочного типа можно сравнивать только на равенство/неравенство. Допустимо сравнение со значением Nil.

q Разыменование (p^). Это унарная операция, ее операнд (p) – указатель, результат – данные по адресу, заданные указателем.


Дата добавления: 2015-12-08; просмотров: 71 | Нарушение авторских прав



mybiblioteka.su - 2015-2024 год. (0.007 сек.)