Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по информатике все.doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
986.62 Кб
Скачать

Операции с указателем

Значением указателя является адрес, поэтому число допустимых операций ограничено. Указателям можно присваивать значения адреса либо процедурой New, либо оператором присваивания, в правой части которого содержится указатель того же ссылочного типа, например:

New(IDin2);

Указателю IDin2 присвоен конкретный адрес памяти динамической переменной IDin2^.

IDin3 := IDin2;

После выполнения этого оператора оба указателя будут содержать адрес одной и той же области памяти. Любому указателю можно присвоить значение специальной константы NIL, например:

IDin2 := NIL;

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

Указатели можно сравнивать между собой и с константой NIL, например:

if IDin2 = IDin3 then IDin2^ : = IDin2^+1; if IDin3 <> NIL then IDin3^ : = 12.5;

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

Пример 41

1. var     I1,I2: ^integer;

Объявлены два указателя на динамические переменные целого типа. Компилятор выделяет две области памяти для хранения адресов - значений указателей I1, I2,которые пока не определены.

2. I2 := NIL;

Указателю I2 присваивается значение константы NIL.

3. New(I1);

Выделяется область памяти для динамической переменной I1^, адрес этой области A1 присваивается указателю I1.

4. I1^ := 12;

Динамической переменной I1^ присваивается значение 12.

5. I2 := I1;

Указателю I2 присваивается тот же адрес, что и в I1, в результате появилась возможность доступа к области памяти, содержащей 12, как по имени I1^, так и по имени I2^.

6. I2^ := I1^ + 1;

Значение переменной I1^, I2^ увеличивается на 1.

7. New(I1);

Для динамической переменной I1^ выделяется новая область памяти по адресу A2, который присваивается указателю I1.

8. I1^ := 23;

Динамической переменной I1^ присваивается значение 23.

9. I2^ := I1^ + 1;

Динамической переменной I2^ присваивается новое значение 24.

10. Dispose(I1);

Уничтожается динамическая переменная I1^, память освобождается, значение указателя I1 становится неопределенным.

Связанные списки

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

Простейшим связанным списком является однонаправленный линейный список, представленный на Рис.3.

Рис.3. Пример линейного однонаправленного связанного списка

Доступ к первой записи списка осуществляется с помощью дополнительного указателя "начало". Поле указателя последней записи содержит значение константы NIL.

Различают:

- линейные и циклические связанные списки

- одно- и двунаправленные списки.

В линейном списке возникают алгоритмические трудности при движении по списку в обратном направлении. Этот недостаток устраняется в двунаправленном списке (Рис.4), каждый элемент которого содержит ссылки на следующий и предыдущий элементы. Указатель первой записи на предыдущий и указатель последней записи на следующий элемент равны значению NIL.

Рис.4. Пример линейного двунаправленного списка

В циклическом однонаправленном списке (Рис.5) указатель последней записи вместо константы NIL содержит адрес первого элемента списка. В этом случае указатель "начало" содержит адрес последнего элемента списка.

Рис.5. Пример циклического однонаправленного списка

Для создания линейного связанного списка в программе необходимо объявить тип записи, в котором одно из полей должно быть ссылочного типа, например:

type ZapDin = ^Zap;

Zap = record

Ukaz: ZapDin;

Info: integer;

end;

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

Просмотр элементов стека осуществляется по принципу LIFO - "последний пришел - первый вышел", т.е. в первую очередь обрабатывается последний элемент, помещенный в список. Просмотр элементов очереди выполняется по принципу FIFO - "первый пришел - первый вышел".