Динамическая память
Все переменные, объявленные в программе, размещаются в одной непрерывной области оперативной памяти, которая называется сегментом данных. Длина сегмента данных определяется архитектурой микропроцессора и не всегда достаточна для обработки больших массивов данных. С другой стороны объем памяти компьютера достаточен для успешного решения задач с большой размерностью данных. Выходом из положения может служить использование так называемой динамической памяти.
Динамическая память – это оперативная память ПК, предоставляемая программе при ее работе, за вычетом сегмента данных, стека и собственно тела программы. Размер динамической памяти можно варьировать в широких пределах. По умолчанию этот размер определяется всей доступной памятью ПК.
Оперативная память ПК представляет собой совокупность элементарных ячеек для хранения информации – байтов, каждый из которых имеет собственный номер. Эти номера называются адресами, они позволяют обращаться к любому байту памяти.
Турбо Паскаль предоставляет в распоряжение программиста гибкое средство управления динамической памятью – так называемые указатели.
Указатель – это переменная, которая в качестве своего значения содержит адрес байта памяти. В ПК адреса задаются совокупностью двух шестнадцатиразрядных слов, которые называются сегментом и смещением. Сегмент – это участок памяти, имеющий длину 65536 байт (64 Кбайт) и начинающийся с физического адреса, кратного 16 (т.е. 0, 16, 32, 48 и т.д.). Смещение указывает, сколько байт от начала сегмента необходимо пропустить, чтобы обратиться к нужному адресу.
Таким образом, по своей внутренней структуре любой указатель представляет собой совокупность двух слов (данных типа word), трактуемых как сегмент и смещение. С помощью указателей можно размещать динамической памяти любой из известных в Турбо Паскале типов данных. Лишь некоторые из них (byte, char, shortint, boolean) занимают во внутреннем представлении один байт, остальные – несколько смежных. Поэтому на самом деле указатель адресует лишь первый байт данных.
Объявление указателей
Как правило, в Турбо Паскале указатель связывается с некоторым типом данных. Такие указатели называются типизированными. Для объявлениятипизированного указателя используется значок ^, который помещается перед соответствующим типом, например:
Var
p1: ^integer;
р2 : ^real;
Type
RecPointer = ^Rec;
Rec = record
Name : string;
Job : string;
Next : RecPointer;
End;
В данном примере при объявлении типа RecPointerуказана ссылка на тип Rec, который предварительно в программе объявлен не был. Как уже отмечалось, в Турбо Паскале последовательно проводится в жизнь принцип, в соответствии с которым перед использованием какого-либо идентификатора он должен быть описан. Исключение сделано только для указателей, которые могут ссылаться на еще не объявленный тип данных. Это исключение сделано не случайно. Динамическая память дает возможность реализовать широко используемую в некоторых программах организацию данных в виде списков. Каждый элемент списка имеет в своем составе указатель на соседний элемент, что обеспечивает возможность просмотра и коррекции списка. Если бы в Турбо Паскале не было этого исключения, реализация списков была бы значительно затруднена.
В Турбо Паскале можно объявлять указатель и не связывать его при этом с каким-либо конкретным типом данных. Для этого служит стандартный тип pointer, например:
Var
р: pointer;
Указатели такого рода называются нетипизированными. Поскольку нетипизированные указатели не связаны с конкретным типом, с их помощью удобно динамически размещать данные, структура и тип который меняются в ходе работы программы.
Как уже говорилось, значениями указателей являются адреса переменных в памяти, поэтому следовало бы ожидать, что значение одного указателя можно передавать другому. На самом деле это не совсем так. В Турбо Паскале можно передавать значения только между указателями связанными с одним и тем же типом данных. Если, например,
Var
p1, p2: ^integer;
p3: ^ real;
pp: pointer;
то присваивание
p1 := p2;
вполне допустимо, в то время как
p1 : = p3;
запрещено, поскольку p1и p3указывают на разные типы данных. Это ограничение, однако, не распространяется на нетипизированные указатели. поэтому можно записать
pp := p3;
p1 := pp;
и тем самым достичь нужного результата.
Дата добавления: 2017-01-29; просмотров: 576;