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

3.4.4 Лабораторные задания

В разработанную ранее согласно заданию 3.3.1 программу добавьте процедуры работы с файлами (рисунок 3.4).

Процедура «Создание файла» использует заранее определенное количество записей файла. Исходные данные компонентов файла вводятся с клавиатуры.

Процедура «Просмотр файла» автоматически определяет количество записей файла и отображает их на экране.

Рисунок 3.4 – Структура программы для задания 3.4.4

3.5 Динамические структуры данных. Указатели

3.5.1 Основные понятия и определения

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

Например, количество компонент файла можно определить только после того, как он будет открыт (после выполнения в программе оператора Reset).

Использовать такую удобную для обработки информации структуру данных, как массив, нельзя, если не известно количество его элементов.

Все объявления в разделе описания переменных требуют точного значения размерности (например, array[1..10]), так как на основе этой информации компилятор «распределяет» память для используемых в программе данных.

Статическое распределение памяти – это распределение памяти в процессе компиляции программы, то есть до начала ее выполнения.

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

Снтаксис:

type

<имя типа> = pointer;

<имя типа> = ^<идентификатор типа>;

Пример:

type

T = pointer; {указатель не связан с определенным типом данных}

T1 = ^integer; {указатель связан с данными целого типа}

var

{ переменные типа указатель}

ptr1: T;

ptr2: T1;

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

  • значение самого указателяадрес динамической памяти.

В приведенном выше примере это значение переменных ptr1, ptr2

  • значение по указателю – значение данных, адрес которых является значением указателя на эти данные. В программе такие значения обозначаются: <имя переменной типа указатель>^

Для указателей ptr1, ptr2 значения по указателю будут обозначаться так: ptr1^, ptr2^ .

Чтобы «почувствовать разницу» между значением указателя и значением данных, адресуемых этим указателем, рассмотрим следующую схему (рисунок 3.5):

Рисунок 3.5 – «Значение указателя» и «значение по указателю»

На рисунке 3.5:

  • После выполнения операции ptrY:= ptrX изменяется значение указателя ptrY и доступ к данным по предыдущему значению этого указателя потерян (данные превращаются в «мусор»)!

  • После выполнения операции ptrY^:= ptrX^ изменяется значение данных по указателю ptrY. Значение указателя ptrY не изменяется!

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