- •Для студентов, обучающихся
- •Основные теоретические положения Действия с указателями
- •Некоторые свойства указателей.
- •Динамические данные
- •Cвязанные динамические данные
- •Организация взаимосвязей в связанных динамических данных
- •Создание очереди
- •Добавление элементов очереди
- •Задание 2
- •Решение
- •Пример 1. Надо упорядочить элементы списка по убыванию, используя сортировку посредством выбора максимального элемента. Используйте список без заглавного элемента. Решение:
- •Библиографический список
- •394000 Воронеж, пр. Революции, 19
Динамические данные
Работа с указателями проиллюстрирована в таблице 2 .
Таблица 2. Работа со статическими и динамическими данными
Структура данных |
Обычные переменные |
Динамические переменные |
1. Простая переменная |
type Tint =1..100; var X : Char; Y : Tint Begin X : = ' * ' ; Y := 3; end. |
type Tint = 1..100; var PX : ^Char; PY : "Tint; begin New (PX); N ew (PY); PX^ : = ' * ' ; PY^ := 3; Dispose (PX) ; Dispose (PY); end. |
2. Массив |
type Vect = array[1..3] of Byte; var X : Vect; i : Byte; begin for i:=l to 3 do Read ( X[i] ); end. |
type Vect = array[l..3] of Byte; var PX : ^Vect; i : Byte; begin New (PX); for i:=l to 3 do Read ( PX^[i] ) ; . . . Dispose (PX) ; end. |
3. Запись |
type Rec = record a : Char; b : Byte end; var X : Rec; begin X.a := '*'; X.b := 7; end. |
type Rec = record a : Char; b : Byte end; var PX : ^Rec; begin New (PX); PX^.a := '*'; PX^.b := 7; . . . Dispose (PX) ; end. |
Рассмотрим пример:
Ввести в память машины 500 целых чисел с помощью генератора случайных чисел, а затем вывести их в обратном порядке.
Решим эту задачу при помощи динамического массива:
program example;
type
Mas = array[1..500] of real; {Тип-массив из 500 чисел}
Pmas = ^Mas; {Тип-указатель на массив из 500 чисел}
const
P: Pmas = nil; {Указатель}
var
i: integer; {Параметр цикла}
begin
New(P); {Выделение памяти для массива на500 чисел}
if P <> nil then {Если память выделена …}
begin
for i:=1 to 500 do {Цикл заполнения массива}
P^[i]:=random(100);
for i:=500 downto 1 do {Цикл вывода чисел}
writeln(P^[i]); {Вывод числа}
dispose(P); {Освобождение области}
end;
end.
Работа с указателями требует осторожности, так как при неправильной работе с ними можно либо потерять динамическую память, либо вызвать ошибку времени выполнения. Если попытаться распределить новую динамическую память с помощью указанных выше стандартных процедур через переменную P, которая уже указывает на выделенную память, то при этом адрес старой выделенной памяти «забывается» и, если нет других указателей на эту память, она становится недоступной, в том числе и для освобождения. Если же попытаться освободить память с помощью переменной P, которая не указывает в данный момент на какую-либо память (например, память уже была освобождена и происходит попытка повторного освобождения памяти), то возникнет ошибка времени выполнения и программа прекратит свою работу. Наконец, если попытаться работать с динамической памятью через переменную P, которая в настоящий момент ни на что не указывает, возможны большие неприятности, вплоть до развала операционной системы.
К сожалению, процедура Dispose не задает после освобождения памяти соответствующей переменной значение nil. Эту операцию при многократном использовании указателя должен выполнить сам программист, а обращаться к памяти (в том числе и освобождать ее) можно только в том случае, когда указатель не равен nil. Целесообразно и в самом начале программы указателям задать значение nil, означающее, что для них еще не выделена динамическая память. Такие дополнительные операции позволят избежать многих неприятных ситуаций при работе программы.
