русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

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


Дата добавления: 2013-12-23; просмотров: 1130; Нарушение авторских прав


New(b);

New(b);

Ссылки динамические переменные

New(b);

New(a);

New(b);

New(a);

Ссылки и динамические переменные

End.

ClrScr;

Begin

Uses WinCRT, A, B;

Program Primer;

X=1

End.

ClrScr;

Begin

Uses WinCRT, B, A;

Program Primer;

X=2

End.

ClrScr;

Begin

Uses WinCRT, A, B;

Program Primer;

End. End.

Interface Interface

Unit A; Unit B;

Особенности выполнения инициирующих разделов

End. End.

....... .......

Uses B; Uses A;

Implementation Implementation

....... .......

Interface Interface

Unit A; Unit B;

Uses CRT, A;

End. End.

....... .......

Uses B; Uses A;

Interface Interface

Unit A; Unit B;

Uses CRT, A, B;

Uses CRT, A;

End.

End.

Uses B; .....

Interface Interface

Unit A; Unit B;

Взаимное использование модулей

Uses CRT, My_modul;

 

Модули могут обращаться друг к другу косвенно или рекурсивно.



При косвенном использовании модулей один из них использует другой:

Пусть в головной программе используется только модуль A:

В этом случае нет необходимости указывать и модуль B:

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

 

Если какой-нибудь из них подключить к программе:

то будет зафиксирована ошибка:

Error 68: Circular Unit Reference (A)

Взаимное использование возможно, если модули подключить из раздела реализации:

 

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

Const x = 1; Const x = 2; x - глобальная

Implementation Implementation переменная

 

 

подключены к программе:

WriteLn('x=', x);

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

Последним подключен модуль B, в котором глобальная x = 2.

Изменим порядок подключения:

WriteLn('x=', x);

В этом случае на экране появится:

так как в модуле A глобальная x = 1.

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

WriteLn('A.x=', A.x);

WriteLn('B.x=', B.x);

На экран будет выведено:

A.x=1

B.x=2

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

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

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

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

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

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

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

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

При первом способе в разделе определения типов Type указывается имя типа ссылки, ставятся знаки = и ^ (карат), указывается тип переменных, к которому будет относиться эта ссылка:

Type TPntint = ^Integer;

TPntchar = ^Char;

TPntReal = ^Real;

В соответствии с этим описанием TPntint является типом ссылки на динамические объекты целого типа, TPntchar – динамические объекты символьного типа, TPntReal – динамические объекты вещественного типа. Сейчас можно описать переменные, значениями которых являются ссылки – переменные ссылочного типа:

Var a, b:TPntint;

x, y: TPntchar;

s, r: TPntReal;

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

Var a, b:^Integer;

x, y: ^Char;

s, r: ^Real;

Переменные a, b, x, y, s, r будут хранить адреса ячеек памяти, где находятся значения одноименных динамических переменных. В порядке исключения такие переменные не описываются в разделе Var, а производятся в программе с помощью оператора New:

……

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

Таким образом, оператор New играет для динамической переменной ту же роль, что и описание для статической.

В Паскале для работы с динамическими переменными введено понятие переменной с указателем – это переменная ссылочного типа, за которой следует символ ^ : x^, y^, a^. Стрелка после имени переменной ссылочного типа говорит о том, что речь идет не о значении данной переменной (адресе ячейки памяти), а о значении одноименной динамической переменной, то есть переменной, на которую указывает эта переменная ссылочного типа.

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

WriteLn(a^, ‘ ‘, b^); на экран будет выведено содержание ячеек
памяти, адреса которых содержатся в

переменных a и b

WriteLn(a, ‘ ‘, b); ошибка! Нельзя выводить на экран адреса

ячеек памяти (Error 64)

a^ := 3;

b^ := 5;

WriteLn(a^, ‘ ‘, b^); на экран будет выведено: 3 5

a := b; переменная a содержит адрес той же ячейки, что и переменная b – они указывают на одну и ту же ячейку памяти

WriteLn(a^, ‘ ‘, b^); на экран будет выведено: 5 5

b := Nil; ссылка b никуда не указывает

WriteLn(a^, ‘ ‘, b^); ошибка! Значение b^ не определено!

Представим для наглядности полученные результаты в виде рисунков, причем в прямоугольниках укажем текущие значения соответствующих переменных, а стрелками – связи между ними:

New(a);

WriteLn(a^, ‘ ‘, b^);

Определены адреса a и b динамических переменных a^ и b^, но сами их значения пока не заданы, поэтому на экран будут выведены значения, оставшиеся в ячейках памяти с указанными адресами после решения предыдущей задачи.

a^ := 3;

b^ := 5;

WriteLn(a^, ‘ ‘, b^);

Обычное присваивание значений переменным: динамической переменной a^ присвоено значение 3, а динамической переменной b^ - значение 5. Эти же значения и выводятся на экран.

a := b;

WriteLn(a^, ‘ ‘, b^);

Указателю a присвоено новое значение – значение адреса ячейки памяти, хранившееся в указателе b. Поэтому сейчас оба указателя хранят один и тот же адрес – адрес b. Они указывают на одну и ту же динамическую переменную b^. Адрес же динамической переменной a^ утерян, поэтому ее значение становится недоступным. Значит, на экран будут выведены два одинаковых числа, являющиеся текущими значениями переменных a^ и b^: 5 и 5.

b := Nil;

WriteLn(a^, ‘ ‘, b^);

 

Указатель b принимает значение пустой ссылки Nil – он перестает указывать на какую-нибудь динамическую переменную b^, поэтому нельзя выводить на экран ее значение.

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

1. вместо описания самих динамических переменных в программе дается описание ссылок на них (статических переменных ссылочного типа), поставленных в соответствие одноименным динамическим переменным,

2. до своего использования каждая динамическая переменная должна быть порождена с помощью оператора New,

3. значение динамической переменной задается с помощью переменной с указателем,

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

Над значениями переменных ссылочного типа – адресами динамических переменных – в Паскале кроме операции присваивания определены две операции сравнения: = и <>.

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

Если в процессе выполнения программы динамический объект, созданный оператором, например New(a), становится ненужным, то его можно уничтожить оператором Dispose(a). При этом динамический объект, на который указывает ссылочная переменная a , уничтожается, занимаемое им место в памяти освобождается, а значение переменной a становится неопределенным. Оператор Dispose уничтожает только сам динамический объект, но не указатель на него:

New(a);

a^ := 3;

b^ := 5;

Dispose(a);

a := b;

 

 

b := Nil;

 

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

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

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

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

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

· размер структуры ограничивается только объемом памяти компьютера,

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

С другой стороны, такие структуры обладают рядом недостатков:

· работа с указателями требует высокой квалификации программиста,

· на указатели расходуется дополнительная память

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



<== предыдущая лекция | следующая лекция ==>
Destination (Memory, Disk) | Добавление нового элемента в список


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.007 сек.