Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по Паскалю.doc
Скачиваний:
61
Добавлен:
04.06.2015
Размер:
7.62 Mб
Скачать

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(a);

New(b);

……

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

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

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

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

New(a);

New(b);

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);

New(b);

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);

New(b);

a^ := 3;

b^ := 5;

Dispose(a);

a := b;

b := Nil;