Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка Паскаль.doc
Скачиваний:
127
Добавлен:
30.04.2015
Размер:
661.5 Кб
Скачать

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

Типизированным называется указатель, который указывает (ссылается) на данные определенного типа. Для его объявления используется символ ^, который размещается перед соответствующим типом данных. Например:

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

Var p1 : ^integer;

p2 : ^mas;

В этом случае p1 – это ссылка (указатель) на целое число, p2 – ссылка на массив из 100 вещественных чисел. Для того, чтобы обратиться к данным по этим адресам, необходимо указать: 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);

Dispose (p2);

После выполнения такой команды память, ранее связанная с указателем, возвращается в кучу (и может быть вновь использована уже для хранения других данных). Однако значение самого указателя не меняется, т.е. в нем остается адрес «несуществующего» (уже отданного обратно в кучу) блока памяти. Поэтому обращение к указателю после выполнения команды Dispose может привести к ошибке.

В паскале существует константа Nil – пустой указатель. Значение Nil может быть присвоено любому указателю, например:

p2 := nil;

Однако выполнение такого присваивания до вызова процедуры Dispose (p2) к тому, что указатель p2 не будет ссылаться ни на какой участок динамической памяти, а данные в памяти останутся, т.е. этот участок не будет возвращен в кучу. Это плохо по той причине, что при выполнении серии таких команд значительная часть динамической памяти будет считаться занятой, но использоваться не будет.

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

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

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

Var p : pointer;

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

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

GetMem ( p, size );

где p – указатель, переменная типа Pointer; size – размер выделяемого участка памяти, выражение типа Word (целочисленный тип). За одно обращение к процедуре GetMem возможно выделение не более 65521 байта памяти (максимальное значение типа Word).

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

FreeMem ( p, size );

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

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