Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
090303 ТП Дин_стр спц.doc
Скачиваний:
12
Добавлен:
01.04.2025
Размер:
504 Кб
Скачать
☆

Динамические данные

Работа с указателями проиллюстрирована в таблице 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, означающее, что для них еще не выделена динамическая память. Такие дополнительные операции позволят избежать многих неприятных ситуаций при работе программы.