Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
выш.мат. методичка.DOC
Скачиваний:
32
Добавлен:
13.02.2015
Размер:
1.71 Mб
Скачать

7.1. Указатель

Указатель в Тurbо Раsсаl дает адрес объекта, определенного типа, называемого базовым типом.

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

Пример

tyре

Mas = аrrау[1..10] оf Reаl; {базовый тип}

Point =^Маs; {тип-указатель на массив из 10 вещественных чисел}

Переменная типа-указателя, которая в дальнейшем будет называться просто указателем, является физическим носителем адреса величины базового типа. Она занимает 4 байта памяти (2 слова). Первое слово дает смещение адреса, а второе - адрес сегмента. Значение этой переменной можно задать процедурой New или GetMem, использованием адресного оператора @, а также присваивание ем ей значения другой переменной этого же типа. Переменной типа-указатель можно также присвоить значение nil, означающее отсутствие ссылки на какой-либо объект (фактически в этом случае переменной присваивается значение 0).

Пример.

typе

Соmplex = record {базовый тип}

Re,Im: Rеаl

end;

Point = ^Соmplех; {тип-указатель}

АdrInt =^Integer; {тип-указатель}

var

X: Соmplех;

Р1, Р2, Р3, Р4: Рoint;

Аd1: AdrInt;

New(Р1); {выделение нового элемента типа Соmplех}

Р2 := @X, {определение адреса переменной, X}

Р3 := Р1; {присвоение значения другого указателя}

Р4 :=nil; {присвоение значения nil}

New(Аd1); {выделение нового элемента типа Integer}

Следует иметь в виду, что указатели, ссылающиеся на объекты разных типов, сами являются объектами разных типов и для них недопустима операция присваивания значений друг другу. Указатели одного и того же типа можно сравнивать помощью операций = и <>.

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

Пример.

Х := Р1^; {переменной Х присваивается значение элемента, на который указывает Р1}

Р3^:=Х; {элементу, на который указывает Р3, присваивается значение переменной X}

Стандартный тип-указатель Роinter дает указатель, не связанный ни с каким конкретным базовым типом. Этот тип совместим с любым другим типом-указателем, однако следует иметь в виду, что использование знака ^ после параметра типа Роinter дает параметр без типа.

В Тurbo Раscal существует операция получения адреса объекта - @, например. Х:=@У; {X - адрес параметра У}

Полученный адрес в версии 7.0 может иметь конкретный тип или быть совмеcтимым с любым указателем. Эти возможности зависят от использования ключа компилятора {$Т+/-}.

7.2. Работа с динамической памятью

Использование указателей совместно с процедурами New и Dispose позволяет осуществлять динамическое распределение памяти.

Процедура New(Р), где Р - указатель, позволяет выделить область памяти такого размера, в котором можно разместить величину базового типа. Указатель значение адреса выделенной области.

Процедура Dispose(Р), где Р - указатель, позволяет освободить область памяти, на которую указывает указатель Р, для последующего использования. После выполнения процедуры значение указателя Р становится неопределенным.

Пример. Ввести в память ПЭВМ 100 вещественных чисел, а затем вывес­ти их в обратном порядке.

рrogram ЕХАМРLЕ;

type

Mas = array [1..100] of Real;

Point =^Mas;

var

P: Point;

i: Word;

begin

New (P) {выделение области для 100 чисел}

WriteLn('Введите 100 чисел');

for i := 1 to 100 do

Read(P^[i]);

for i := 100 down 1 do

WriteLn(Р^[i]);

Disposе(Р) {освобождение области}

end.

Существует и другая возможность работать с динамической памятью - использовать процедуры GetMem и FreeМеm.

Процедура GetMem(Р,Size), где Р - переменная типа-указатель (в том числе типа Роinter), а Size - выделяемая область памяти в байтах, позволяет выделить в динамической памяти область необходимого размера, при этом адрес выделенной области присваивается переменной Р.

Процедура FreeNem(Р,Size) - здесь параметры те же, что и в процедур GetMem, - освобождает занятую область памяти с адресом, задаваемым переменной Р и размером Size байтов. Эта область становится свободной для повторного использования, а указатель Р становится неопределенным.

Наконец, для управления динамической памятью существует еще две процедуры: Маrk и Rеleаsе.

Процедура Маrk(Р), где Р - переменная типа Рointer, фиксирует текущее состояние динамической памяти, записывая в переменную Р значение указателя свободной области динамической памяти.

Процедура Release(Р), где Р - переменная типа Pointer, позволяет вернуться к состоянию динамической памяти, определяемому переменной Р, которой был присвоено значение процедурой Маrk. При этом динамическая память, занятая после выполнения процедуры Маrk с адресами больше адреса, зафиксированного в указателе Р, освобождается.

Во избежание ситуаций, приводящих к неправильной работе с динамической памятью, нежелательно использовать процедуру Release попеременно с процедурами Dispose и FreeМеm.