Тема: Динамические переменные.

 

План занятия.

  1. Что такое указатели.
  2. Описание указателей.
  3. Стандартные процедуры и функции для работы с указателями.
  4. Использование динамических переменных при работе с модулем Graph.

Скачать:

ВложениеРазмер
Microsoft Office document icon lekciya_10.doc40.5 КБ

Предварительный просмотр:

Лекция 10

Тема: Динамические переменные.

План занятия.

  1. Что такое указатели.
  2. Описание указателей.
  3. Стандартные процедуры и функции для работы с указателями.
  4. Использование динамических переменных при работе с модулем Graph.

  1. Что такое указатели

При выполнении программы каждая используемая в ней переменная получает свой адрес в оперативной памяти. Программисту не нужно заботиться о механизме распределения адресов, это делается автоматически. Машина сама ищет свободное место в памяти и выделяет в ней место для переменных. В Турбо-Паскале есть два способа распределения памяти: статический и динамический. При статическом распределении всем объявленным в программе переменным в сегменте данных выделяются фиксированные участки оперативной памяти. В связи с этим использование заранее не объявленных переменных не допускается. При динамическом распределении памяти имеется возможность создавать новые, не объявленные заранее переменные и размещать их на свободные участки в динамической области оперативной памяти. Это достигается за счет использования указателей.

Указатель – это элемент данных, представляющий собой ссылку на опредленную ячейку оперативной памяти (т.е. адрес ячейки), начиная с которой записывается значение переменной. Переменные, которые размещаются в оперативной памяти динамическим способом с помощью указателей, называются динамическими переменными.

Указатель может принимать значения, равные всем адресам оперативной памяти, по которым возможна запись данных. Указатель может иметь стандартное значение Nil (пусто), которая говорит что соответствующая переменная в динамической памяти отсутствует (в указателе не содержится никакого адреса).

  1. Описание указателей

Указатель объявляется с помощью специального символа каре (^), за которым записывается идентификатор типа динамической переменной:

Type имя_типа=^тип;

Var имя переменной=имя типа;

Или

Var имя переменной:^имя типа;

Например:

A,B,C:^Integer;

В этом случае переменные A,B,C являются указателями на переменные типа Integer. Для обращения к значениям этих переменных служат идентификаторы A^,B^,C^, то есть имя переменной и знак каре.

Кроме того, указатель может быть объявлен явно следующим образом:

Var p:Pointer;

Значения указателей можно сравнивать только с помощью проверки на равенство и неравенство. Допустимо также использование оператора присваивания. Для динамических переменных (A^,B^,C^) допустимы все те же операции, что и над обычными переменными данного типа.

3. Стандартные процедуры и функции для работы с указателями

1. Любым действиям с динамической переменной должна предшествовать процедура ее размещения в ОЗУ. Эта процедура имеет вид:

New(var p:Pointer);

Она создает новую динамическую переменную, присваивая указателю р значение ее адреса в ОЗУ. При этом динамической переменной отводится блок памяти, соответствующий  размеру типа, с которым объявлен указатель р.

2. Когда в ходе вычислительного процесса переменная становится ненужной, ее следует удалить. Это осуществляется с помощью процедуры

Dispose(var Pointer);

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

type

  Str18 = string[6];

var

  P: ^Str18;

begin

  New(P);

  P^ := 'Hellow';

  Writeln(p^);

  Dispose(P);

end.

3. GetMem(Var p:Pointer, Size:Word);

Word – 2 байта (Целые числа от 0 до 65535)

Создает новую динамическую переменную размером Size байт, устанавливая значения указателя р на начало выделяемой ей динамической области оперативной памяти.

  1. FreeMem(Var p:Pointer, Size:Word);

Уничтожает динамическую переменную, освобождая Size байт. После выполнения процедуры FreeMem значение р становится неопределенным.

  1. Mark(Var p:Pointer) – запоминает состояние динамической области памяти в указателе р для того, чтобы в дальнейшем все динамические переменные, размещенные в оперативной памяти после выполнения Mark, могли быть уничтожены.
  2. Release(Var p:Pointer) – уничтожает все динамические переменные, размещенные в ОЗУ после указателя р. Значение р обычно формируется с помощью процедуры Mark.

var

  p : pointer;

  p1,p2,p3 : ^Integer;

begin

  New(p1); { Создает указатель на переменную Integer }

  Mark(p); { Запоминает состояние (Все дальнейшие указатели будут разме

           щаться за указателем р)}

  New(p2); { Создает указатели на еще две переменных Integer }

  New(p3);

  Release(p); { Память выделенная для р2^, p3^ освобождена,

              но р1^ все еще можно использовать}

end.

Функции:

  1. MaxAvail: LongInt (-2147483648..2147483647  - 4 байта) – возвращает размер (в байтах) наибольшего непрерывного блока в динамической памяти, где может быть размещена динамическая переменная.
  2. MemAvail:LongInt – возвращает размер свободной области динамической памяти.
  3. Addr(X):Pointer – возвращает адрес объекта, где Х – любая переменная, имя процедуры или функции.

Операция @ позволяет получить указатель на переменную, процедуру или функцию (т.е. ее адрес).

  1. Использование динамических переменных при работе с модулем Graph.

При работе в графическом режиме часто возникает необходимость запоминания определенной части графического изображения в отдельной области ОЗУ для того, чтобы в дальнейшем быстро восстановить это изображение на экране. Использование оперативной  памяти для сохранения графических изображений полезно для обеспечения запоминания последовательности меню, для программирования движущихся изображений и т.д.

Сохранение и восстановление графических изображений обеспечивается следующими процедурами и функциями модуля Graph:

GetImage(X1,Y1,X2,Y2:Integer; Var BitMap); - сохраняет в оперативной памяти образ прямоугольной области графического изображения экрана. Х1,Y1 – координата левого верхнего угла, Х2,Y2 – правого нижнего угла. Изображение запоминается в переменной BitMap. Размер переменной должен быть на 4 байта больше, чем необходимо для сохранения данного объема графического изображения, поскольку в этих байтах запоминается высота и ширина сохраняемой прямоугольной области экрана.

ImageSize(X1,Y1,X2,Y2:Integer;):Word; - возвращает количество байт, необходимое для сохранения прямоугольной области графического изображения экрана с координатами X1,Y1,X2,Y2. Возвращаемое ImageSize значение включает необходимую память для запоминания высоты и ширины прямоугольной области (+4 байта). Если объем оперативной памяти, необходимой для сохранения прямоугольной области экрана больше 64Кб, то ImageSize=0, GraphRezult=-11.

PutImage(X1,Y1:Integer; Var BitMap; BitBit:Word) – выводит на экран сохраненный в BitMap образ прямоугольной области графического изображения экрана. Место на экране, в которое будет выводиться изображение, задается координатами X1,Y1 – левый верхний угол прямоугольной области. Переменная BitBit задает режим вывода на экран сохраненного изображения.  Для нормального вывода изображения используется значение 0 или NormalPut.

Для создания движующегося изображения необходимо:

  1. определить размер прямоугольной области экрана, в котором находится изображение (ImageSize);
  2. выделить блок памяти, необходимый для размещения прямоугольной области экрана(GetMem);
  3. запомнить изображение в памяти (GetImage);
  4. выводить изображение из памяти на экран, изменяя его координаты (PutImage).