Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа по динамическим массивам (№...doc
Скачиваний:
2
Добавлен:
04.09.2019
Размер:
160.26 Кб
Скачать

2

«УТВЕРЖДАЮ»

Ректор университета

_________________А.В. Лагерев

«________»_____________2006г.

Алгоритмические языки и программирование Работа с динамическими массивами

Методические указания к выполнению лабораторной работы №13

для студентов дневной формы обучения

специальностей 075300 – "Организация и технология

защиты информации",

220300 – "Системы автоматизированного проектирования"

Брянск 2006

УДК 004.43

Алгоритмические языки и программирование. Работа с динамическими массивами: методические указания к выполнению лабораторной работы №13 для студентов дневной формы обучения специальностей 075300 – "Организация и технология защиты информации", 220300 – "Системы автоматизированного проектирования".– Брянск: БГТУ, 2006. - 12 с.

Разработал: Ю.А. Леонов, асс.

Научный редактор Ю.М. Казаков

Редактор издательства Л.И. Афонина

Компьютерный набор Ю.А. Леонов

Рекомендовано кафедрой «Компьютерные технологии и системы» БГТУ (протокол № от )

Темплан 2006г., п.

Подписано в печать Формат 60х84 1/16. Бумага офсетная. Офсетная печать.

Усл. печ. л. 1,45 Уч. – изд. л. 1,45 Тираж 50 экз. Заказ Бесплатно

Брянский государственный технический университет.

Брянск, бульвар 50-летия Октября, 7, тел. 55-90-49.

Лаборатория оперативной полиграфии БГТУ, ул. Институтская, 16

  1. Цель работы

Овладеть практическими навыками работы с динамическими массивами, научиться выполнять основные операции над ними.

Продолжительность работы – 6ч.00мин.

  1. Теоретическая часть

При объявлении данных динамической структуры в разделе описаний указывается не сама переменная какого – либо типа, а указатель на неё.

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

Нетипизированные указатели объявляются следующим образом:

Var

pp: pointer;

Описание типизированных указателей выглядит следующим образом:

Var

px: ^char;

py: ^integer;

Для работы с динамическими переменными в программе должны быть предусмотрены:

  • выделение памяти под динамическую переменную;

  • присвоение динамической переменной адреса выделенной памяти (инициализация указателя);

  • освобождение памяти после использования динамической переменной.

Выделение и освобождение памяти под динамические переменные выполняется стандартными процедурами New, Dispose, GetMem, FreeMem во время работы программы.

Описание основных процедур и функций предназначенных для работы с динамической памятью

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

Procedure New (var p: pointer);

Процедура Dispose освобождает область памяти, на которую указывает указатель p, после чего эта область памяти становится доступной для распределения под другие динамические переменные.

Procedure Dispose (var p: pointer);

Процедура GetMem создаёт новую динамическую переменную указанного размера, и помещает адрес блока в переменную – указатель.

Procedure GetMem (var p: pointer; Size: Word);

Size – выражение, определяющее размер выделяемой области памяти в байтах.

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

Procedure FreeMem (var p: pointer; Size: Word);

Функция SizeOf возвращает число байт, занимаемых аргументом, указанным в качестве параметра функции.

Function SizeOf (x): integer;

Функция MaxAvail возвращает размер самого большого непрерывного свободного участка в «куче» (динамически распределяемая область памяти). Возвращаемый функцией результат представляет собой значение, принадлежащее типу LongInt.

Function MaxAvail: LongInt;

Функция MemAvail возвращает общее количество свободной памяти в «куче» с учетом фрагментации.

Function MemAvail: LongInt;

Особенности работы с одномерными динамическими массивами

К сожалению, на языке Pascal нет удобных стандартных средств для работы с динамическими массивами, но существует обходные пути для реализации динамических массивов в языке Pascal.

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

В языке Pascal имеются инструменты для работы со статическими массивами, а также инструменты для выделения динамической памяти, если грамотно сложить достоинства этих возможностей, то получится вполне удобный инструмент для работы с динамическими массивами. Для того чтобы пользоваться удобным инструментом доступа к элементам массива, т.е. обращение к элементам массива через указание индекса [индекс], необходимо для создания динамического массива объявить статический массив, состоящий из одного элемента.

Например: TMass=array [1..1] of integer;

Также для работы с инструментом динамического выделения памяти необходимо ввести указательный тип данных на ранее объявленный статический массив.

Например: TPMass=^TMass;

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

Var PMass: TPMass;

GetMem (PMass, sizeof (TMass)* size);

Процедуре GetMem передается указательная переменная, в которую будет записан адрес на начало выделенной памяти и размер памяти в байтах. Для того чтобы подсчитать необходимое количество памяти для создания динамического массива нужно перемножить размер памяти, занимаемый одним элементом на количество элементов массива. Размер памяти под один элемент можно подсчитать с помощью стандартной функции sizeof (результат в байтах).

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

FreeMem (PMass, sizeof (TMass)* size);

Освобождается память, выделенная под динамический массив аналогично выделению памяти.

Для того чтобы обратится к элементу динамического массива необходимо воспользоваться операцией разыменования (обращение к данным по адресу) и инструментом обращения к элементам статического массива (через указание индекса массива с помощью квадратных скобок [ ]).

Например, присвоим переменной k значение, находящееся в динамическом массиве в ячейке с индексом 3:

K:=PMass^[3];

Несмотря на то, что статический массив содержит всего лишь один элемент, именно из этих «кирпичиков» строится динамический массив, обращаться в динамическом массиве можно к любому его элементу. Для того чтобы в ходе выполнения программы не возникала ошибка при событии выхода за пределы массива необходимо отключить в настройках среды программирования опцию «Range checking» (контроль выхода за диапазон) Option | Compiler | Runtime errors. При отключении данной опции компилятор не вставит в машинный код обработчик данной ошибки, т.е. в этом случае можно выходить за пределы объявленного массива. Другой вариант в начале программы вставить директиву компилятора {$R-}, данная директива сообщает компилятору, что в получаемый в результате компилирования машинный код не надо вставлять обработчик контроля выхода за диапазон, т.е. этот вариант аналогичен описанному ранее.

Особенности работы с двумерными динамическими массивами

Так же как и в случае с одномерными динамическими массивами стандартных инструментов для работы с двумерными динамическими массивами отсутствуют. Существует очень красивое решение для реализации динамических массивов на языке Pascal. Построим схему данных, которая будет давать представление о том, как распределяются данные двумерного динамического массива.

Схема данных двумерного динамического массива размерностью 3х3 выглядит следующим образом:

**

*

4

5

1

*

3

2

3

*

8

4

3

На данной схеме набором из двух звездочек ** обозначен двойной указатель, т.е. переменная указатель, в которой хранится адрес на данные указательного типа (адрес на адрес). Одной звездочкой * обозначается адрес на целочисленные данные. В нашем случае двойной указатель ссылается на столбец указателей. Каждый из элементов этого столбца указывает на строку данных, в нашем случае набор целых чисел. Пользуясь приведенной схемой можно выделить память под двумерный динамический массив.

Можно представить следующий алгоритм выделения памяти под двумерный динамический массив:

  • объявление двойного указателя;

  • выделение памяти под столбец указателей;

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

Для работы с динамическим массивом нужно объявить необходимые типы данных.

TMass=array [1..1] of integer; {тип массив для представления данных целого типа}

TPMass=array [1..1] of ^TMass; {тип массив для представления данных указательного типа}

TPPMass=^TPMass; {тип данных двойного указателя}

Выделим память под двумерный динамический массив.

GetMem(PPMass, sizeof(TPMass) * row); {выделяем память под столбец указателей}

for i:=1 to row do GetMem(PPMass^[i], sizeof(TMass) * col); {выделяем память под данные целого типа с занесением адреса в каждую ячейку столбца указателей}

Обратиться к ячейке двумерного динамического массива можно аналогичным образом, как и в случае с одномерным динамическим массивом.

Например, присвоим переменной k значение, находящееся в динамическом массиве в ячейке с индексом 3, 4:

k:=PMass1^[3]^[4];

Для полного понимания работы с двумерным динамическим массивом необходимо подробно ознакомиться с особенностями работы с одномерными динамическими массивами.