Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Методичка Паскаль

.pdf
Скачиваний:
101
Добавлен:
30.04.2015
Размер:
592.26 Кб
Скачать

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

Указатели

Указатель – это переменная целого типа, которая интерпретируется как адрес какого-либо элемента данных (переменной, константы, адреса дру-

гого элемента данных). Т.е. указатель это адрес. Кроме этого, употребля-

ют термин ссылка. Это синонимы.

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

Например, после исполнения команды присваивания p := Addr (a);

в переменную p будет записан адрес1 переменной a. Вместо функции

Addr можно использовать оператор @. То есть, вместо записанной выше ко-

манды можно написать: p := @a;

В языке Турбо Паскаль указатели бывают двух видов – типизирован-

ные и нетипизированные.

Типизированные указатели

Типизированным называется указатель, который указывает (ссылает-

ся) на данные определенного типа. Для его объявления используется символ

^, который размещается перед соответствующим типом данных. Например:

Type mas = array[1..100] of real;

Var p1 : ^integer;

p2 : ^mas;

В этом случае p1 – это ссылка (указатель) на целое число, p2 – ссылка на массив из 100 вещественных чисел. Для того, чтобы обратиться к данным

1 Память в персональном компьютере адресуется двумя шестнадцатеричными словами (BA:BS), где BA - сегментный адрес, BS - смещение. Сегмент – участок памяти длиной 64 Кбайта, который начинается с физического адреса, значение которого кратно числу 16. Смещение определяет номер байта в сегменте.

91

по этим адресам, необходимо указать: p1^, p2^. То есть, p1 – это адрес, а p1^

- то, что по этому адресу находится.

Для выделения участка динамически распределяемой памяти (кучи) в

целях размещения там необходимых данных используется стандартная про-

цедура

New (p); , где p – указатель.

После выполнения такой команды будет выделен блок памяти необхо-

димого размера (для размещения тех данных, на которые ссылается указатель p), а сам указатель p приобретет значение адреса этого выделенного участка памяти. Например, после выполнения команд:

New (p1);

New (p2);

будет выделено два непрерывных участка кучи, первый размером 2

байта (т.к. целое число занимает 2 байта оперативной памяти), второй – 400

байтов (100 * 4 байта для каждого из 100 вещественный чисел).

После выполнения этих команд указатели p1 и p2 приобрели конкрет-

ные значения. Поэтому по адресам, на которые они указывают, можно раз-

мещать конкретные значения соответствующего типа. Например, p1^ := 52;

p2^[1] := 8;

Если в момент выполнения процедуры New в куче не окажется непре-

рывного участка памяти требуемого размера, то программа аварийно завер-

шится с сообщением «Out of Memory». Для контроля размера доступного участка в динамически распределяемой памяти (куче) можно использовать функцию MaxAvail, которая возвращает размер максимального непрерыв-

ного участка кучи в текущий момент времени.

Для освобождения динамической памяти используется процедура

Dispose (p); , где p – указатель.

Например:

Dispose (p1);

92

Dispose (p2);

После выполнения такой команды память, ранее связанная с указате-

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

ния других данных). Однако значение самого указателя не меняется, т.е. в

нем остается адрес «несуществующего» (уже отданного обратно в кучу) бло-

ка памяти. Поэтому обращение к указателю после выполнения команды Dispose может привести к ошибке.

В паскале существует константа Nil – пустой указатель. Значение Nil

может быть присвоено любому указателю, например: p2 := nil;

Однако выполнение такого присваивания до вызова процедуры

Dispose (p2) к тому, что указатель p2 не будет ссылаться ни на какой участок динамической памяти, а данные в памяти останутся, т.е. этот участок не бу-

дет возвращен в кучу. Это плохо по той причине, что при выполнении серии таких команд значительная часть динамической памяти будет считаться за-

нятой, но использоваться не будет.

Константа Nil необходима при работе с динамическими структурами данных, что будет рассмотрено ниже.

Нетипизированные указатели

Нетипизированным называется указатель, не связанный с каким-то конкретным типом данных. Для его описания используется стандартный тип

Pointer. Например,

Var p : pointer;

Нетипизированные указатели используются для динамического разме-

щения данных, структура и тип которых могут меняться в ходе выполнения программы.

Для выделения памяти используется стандартная процедура

GetMem ( p, size );

где p – указатель, переменная типа Pointer; size – размер выделяемого участ-

ка памяти, выражение типа Word (целочисленный тип). За одно обращение к

93

процедуре GetMem возможно выделение не более 65521 байта памяти (мак-

симальное значение типа Word).

Для освобождения памяти и возвращения ее в кучу используется стан-

дартная процедура

FreeMem ( p, size );

где p – указатель, переменная типа Pointer; size – размер освобождаемого участка памяти, выражение типа Word.

Константу Nil можно использовать и при работе с нетипизированными указателями.

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

Динамическими называют структуры данных, динамически создавае-

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

ти. К ним относятся списки: однонаправленные (стек, очередь), двунаправ-

ленные; графы (и прежде всего дерево как ориентированный граф).

Стек

Стеком называется структура данных, организованная по правилу

LIFO: last input – first output, т.е последним вошел – первым вышел.

Глубина стека – количество элементов в нем.

Вершина стека – «верхний», т.е. доступный элемент.

Стек как структуру данных, размещенную в динамической памяти,

можно представить как «цепочку» записей (Record), одно из полей которых есть указатель на предыдущий элемент. Стек из четырех элементов «выгля-

дит» в памяти так, как изображено на Рис. 8:

указатель на вершину стека

4-й эл-т

 

3-й эл-т

 

2-й эл-т

 

1-й эл-т

Nil

 

 

 

 

 

 

 

 

ссылка

 

ссылка

 

ссылка

 

ссылка

 

 

 

 

 

 

 

 

 

Рис. 8. Стек из четырех элементов

94

Примеры решаемых задач Пример 1. Составить программу, которая формирует стек из 10 эле-

ментов, а затем удаляет его из памяти.

Программа:

Program stack10;

Uses Crt;

Const n=10;

Type stack = ^elem; elem = Record

num : Integer; p : stack

End;

Var st,beg_st : stack;

i : Integer;

Begin

Clrscr; beg_st := nil;

For i := 1 To n Do

Begin

New (st);

st^.p := beg_st; beg_st := st;

Write ('введите ', i ,' элемент стека ');

Readln (st^.num)

End;

Writeln ('в динамической памяти создан стек:'); st := beg_st;

While st <> nil Do

Begin

Writeln (st^.num);

95

st:=st^.p

End;

Readln;

Writeln ('Освобождаем память - удаляем элементы стека из кучи '); i := n;

st := beg_st;

While beg_st<>nil do

Begin

st := beg_st;

Writeln ('Удалили ', i ,' элемент '); beg_st := st^.p;

i := i - 1; Dispose (st);

End;

Readln

End.

Контрольные задания

14.1. Составить программу, которая создает стек из N элементов (про-

извольного типа) и:

a.) выводит содержимое стека на экран; b.) вставляет элемент в стек на k-е место; c.) удаляет элемент с номером k из стека.

14.2. Составить программу, которая создает очередь из N элементов

(произвольного типа) и:

a.) выводит элементы очереди на экран;

b.) вставляет элемент в очередь на k-е место; c.) удаляет элемент с номером k из очереди.

14.3. Составить программу, которая формирует двунаправленный спи-

сок из N элементов (произвольного типа) и:

96

a.) выводит элементы списка на экран;

b.) вставляет элемент в список на k-е место; c.) удаляет элемент с номером k из списка.

97

Список литературы

1.Алексеев Е.Р. Турбо Паскаль 7.0. М.: НТ Пресс, 1996.

2.Грызлова Т.П., Грызлов В.И. Турбо Паскаль 7.0: для школьников,

студентов и преподавателей. Изд. 4-е, испр-е. М.: ДМК Пресс, 2005.

3. Кораблев В. Турбо Паскаль 7.0. Самоучитель. Изд. 16-е . Спб.: Пи-

тер, 2005.

4. Немнюгин С., Перколаб Л. Изучаем Турбо Паскаль. Спб.: Питер,

2004.

5. Попов В.Б. Турбо Паскаль для школьников. М.: Финансы и стати-

стика, 2004.

6. Фаронов В.Р. Турбо Паскаль 7.0: начальный курс. М.: Нолидж,

1997.

7. Чеснокова О.Р. Турбо Паскаль 7.0. Шаг за шагом. М.: НТ Пресс,

2004.

98

Газейкина Анна Ивановна

Основы структурного программирования на языке Паскаль

Учебно-методическое пособие/ Урал. гос. пед. ун-т.

Оригинал-макет подготовлен автором

ЛР №040330 от 18.04.97

Подписано в печать Формат 60х84 1/16 Печать плоская. Бумага для множ. апп.

Гарнитура Таймс. Усл. печ. л. 6 . Тираж 100 экз. Заказ

Уральский государственный педагогический университет 620017, г. Екатеринбург, пр. Космонавтов, 26.

Тираж отпечатан в отделе множительной техники

99