Ссылочные типы в ТП
Указатели и динамические переменные
Переменные ссылочного типа (или указатели) описываются в разделе описания переменных, а их тип, указывающий на тип создаваемых в программе, соответствующих динамических объектов определяется либо путем задания типа в описании переменных, либо путем указания имени ранее описанного типа. Значением указателя является адрес ячейки памяти, начиная с которой будет размещен в памяти соответствующий динамический объект. Задание ссылочного типа выполняется по схеме:
Type имя ссылочного типа=^ имя типа динамического объекта;
Например: Type mas=array[1..1000] of real;
Var p,q:^integer; c:^char; a: ^mas;
Эти описания означают, что значениями указателей p и q являются адреса ячеек, где будут размещены динамические переменные целого типа, указатель с – ссылка на динамическую переменную символьного типа, указатель а – ссылка на динамический массив из 1000 вещественных чисел. Связь указателя с динамическим объектом можно изобразить следующим образом:
Р – имя указателя, звездочкой изображено значение указателя, а стрелка отражает тот факт, что значение указателя является адрес объекта (ссылка на объект), посредством которой объект и доступен в программе
Кроме того, объектом указателя Р является и специальная ссылка nil (ничего), так называемая пустая ссылка, т.е. ссылка, не указывающая ни на какое место в памяти. Результаты выполнения оператора р:=nil можно изобразить следующим образом:
Прежде чем работать с динамическим объектом, необходимо выделить для него место в памяти с помощью процедуры new(p), где р – имя указателя. Процедура new(p) выполняет две функции:
- Резервируется место в памяти для размещения динамического объекта соответствующего типа с именем p^.
- Указателю р присваивается адрес создаваемого динамического объекта p^.
Узнать адрес динамической переменной с помощью процедуры writeln(p) нельзя. Динамические объекты размещаются в специальной области памяти, свободной от программ и статических переменных – heap – области. Пример 1.
var p:^integer; q:integer; Begin new(p); {порождается динамическая переменная целого типа} P^:=50; {динамической переменной присвоено значение 50} Q:=p^+2; p^:=p^ div 3; p^:=q; {допустимые операторы} P:=q; q:=p+2;p:=p^+3; {недопустимые операторы} End.
Если в процессе выполнения программы некоторый динамический объект p^, созданный в результате выполнения оператора new(p), становится ненужным, то его можно уничтожить (очистить выделенное ему место в памяти) с помощью стандартной процедуры dispose(p). В результате выполнения этой процедуры значение указателя р становится неопределенным, но не равным nil. Пример 2.
Program ex2; Var i:integer; p,q:^integer; {рис.1а} Begin New(p); new(q); i:=5; {рис.1б} P^:=7; q^:=p^-i; i:=i+1; {рис.1в} P^:=q^+i; q:=p; write(q^); {рис 1г} End.
Место в памяти, ссылка на которое прежде являлась значением переменной q, теперь стало недоступным: нельзя, например, воспользоваться записанным там значением, нельзя освободить это место с помощью dispose, поскольку на него нет ссылки. Это место в памяти представляет так называемый «мусор». От него следовало бы избавиться с помощью процедуры dispose(q) до изменения значения переменной q. Заменим три последних оператора в программе ех2 на следующую группу операторов: P^:=q^+i; dispose(q);q:=p; write(q^); {рис 2a}
Примечание. Если в ситуации, изображенной на рис.2а, выполнить dispose(p), то место в памяти, ссылка на которое была значением переменных p и q, освободится. После этого не только значение переменной р, но и значение переменной q будет неопределенным.
Стандартные процедуры new и dispose позволяют динамически порождать программные объекты и уничтожать их, что дает возможность использовать память компьютера более эффективно.
Составить программу, которая в вещественном массиве с 1500 элементами находит элемент, номер которого равен наибольшему значению массива, состоящему из 3000 целых чисел. Алгоритм решения.
- организуем динамический массив из целых чисел [1..3000]
- найдем в нем наибольший элемент к
- освободим память от этого массива и создадим динамический массив действительных чисел
- найдем элемент в этом массиве, номер которого равен к.
program ex3; uses crt; type ra=array[1..1500]of real; ia=array[1..3000] of integer; var k,i:integer; p:^ra;q:^ia; Begin clrscr; randomize; k:=0; new(q); for i:=1 to 30 do begin q^[i]:=random(15)+6; write(q^[i]:4); if q^[i]>k then k:=q^[i]; end; writeln; writeln; writeln('k= ',k);dispose(q); new(p); for i:=1 to 30 do begin p^[i]:=random(15)+random; write(p^[i]:5:1); end; writeln; writeln; writeln('iskom element = ', p^[k]:4:1); readkey; End.
Назад
Далее