
- •Конспект лекций
- •Тема 1. Программные средства пк. Основы алгоритмизации задач.
- •Тема 2. Программирование на базовом процедурно-ориентированном алгоритмическом зыке. Классификация операторов алгоритмического языка. Оператор присваивания. Операторы управления. (2 часа)
- •Тема 3. Описание линейных и разветвляющихся структур алгоритмов. Программирование разветвляющихся структур.(1 часа)
- •Тема 4. Организация выполнения программ на пк. Структуры данных: массивы. Множества. Записи. (2 часа)
- •Тема 5. Организация алгоритмов циклической структуры. Алгоритмическое описание вложенных циклических структур. (1 часа)
- •Оператор цикла с параметром
- •Оператор цикла с постусловием
- •Примеры бесконечных циклов
- •Тема 6. Программирование ввода-вывода массивов. Строковые данные. Библиотека стандартных подпрограмм. (1 часа)
- •Тема 7. Подпрограммы, их классификация. (1 часа)
- •Параметры-значения
- •Тема 8. Алгоритмы поиска и сортировки. (1 часа)
- •Тема 9. Программирование в среде delphi. (1 часа)
- •Тема 10. Работа с файлами. Различные типы файлов.
- •Тема 11. Динамические структуры данных. Указатели. Работа с очередями и стеком. (2 часа)
- •Добавление в конец списка
- •Рекурсивная процедура добавления элемента в список
- •Включение в список
- •Рекурсивная процедура удаления элемента из списка
- •Тема 12. Машинная графика.Примеры программ с различной структурной организацией. (1 часа)
- •Литература
Тема 11. Динамические структуры данных. Указатели. Работа с очередями и стеком. (2 часа)
План лекции 13:
Ссылочный тип
Статические, динамические переменные
На языке Паскаль, программист может решать вопросы динамического распределения памяти, используя ссылочный тип данных.
Ссылочный тип определяется в следующем виде:
type
<имя ссылочного типа>=^<имя базового типа>;
Примеры:
type
mas=array[1..10] of integer;
Ptr= ^integer;
link = ^mas;
linkchar = ^char;
tie = ^real;
Описание переменных ссылочного типа:
var
p:ptr;
v:link;
a:^real;
Значение ссылочного типа (неформально) – адрес в памяти, где располагается конкретное значение базового типа. Есть специальный указатель, который «никуда не указывает». В адресном пространстве оперативной памяти выделяется один адрес, в котором заведомо не может быть размещена никакая переменная. На это место в памяти и ссылается такой пустой или «нулевой» указатель, который обозначается служебным словом nil.
Указатель nil считается константой, принадлежащей любому ссылочному типу. Иными словами, это значение можно присваивать любому указательному типу.
Сравнение на равенство (=), сравнение на неравенство (<>)
– ссылаются ли два указателя на одно и то же место в памяти?
Примеры: var p1,p2:ptr;
......
sign:=p1=p2;
if p1<>nil then ....
Для того чтобы по указателю на переменную получить доступ к самой этой переменной, необходимо после переменной-указателя поставить знак '^'; p1^ есть «переменная», на которую ссылается p1. Такая конструкция может находиться в любом контексте, в котором допустимо нахождение самой указываемой переменной. Если p1 имеет тип ^integer, то p1^ имеет тип integer.
Разыменование некорректно, если ссылочная переменная имеет значение nil.
Поэтому p1:=nil;
p1^:=2;
некорректно и приводит к трудно распознаваемым ошибкам.
Пример: var p1,p2:^integer;
Пусть переменные p1^ и p2^ уже имеют значения 1 и 2 соответственно (как это сделать смотрите ниже). Тогда различные результаты следующих присваиваний изображены на рис. 1.
p1:=p2;
p1^:=p2^;
Исходное состояние:
После присваивания p1:=p2
После присваивания p1^:=p2^
Рис.1 Различия в присваиваниях
Динамические переменные – это те, которые образуются и уничтожаются в произвольный момент выполнения программы.
Средство доступа к статическим переменным есть идентификатор. Динамические переменные, количество которых и место расположения в памяти неизвестны, невозможно обозначить идентификаторами. Средство доступа к динамическим переменным – указатель на место их текущего расположения в памяти.
Процедура new(<переменная ссылочного типа>) предназначена для создания динамической переменной:
в динамической области памяти отводится место для хранения переменной, тип которой совпадает с базовым типом указателя-переменной;
переменной, переданной в параметре, присваивается указатель на отведенную область памяти.
Пример: type
mas=array[1..10] of integer; link=^mas;
var t:link;
........
new(t);
Отводится память, достаточная для хранения массива типа mas. Переменной t присваивается адрес этой памяти. Теперь возможен доступ к элементам массива, например:
t^[i]:=0;
t^[i]:=t^[j];
Переменная t является статической, место в памяти для ее значения выделено при трансляции. Переменная t^ – динамическая, она появляется только при выполнении процедуры new(t).
Процедура dispose(<переменная ссылочного типа>) служит для освобождения памяти, отведенной с помощью процедуры new с той же переменной.
Рис. 2 иллюстрирует применение процедур new и dispose (переменные p1 и p2 имеют тип ^integer):
new(p1);new(p2);
p1^:=1; p2^:=2;
p1:=p2;
dispose(p2);
Рис. 2 Результат выполнения фрагмента
План лекции 14:
Линейный список
Циклически связанный список
Создание и обработку структур данных, компоненты которых связаны явными ссылками. Особое значение придается структурам простой формы; приемы работы с более сложными структурами можно получить из способов работы с основными видами структур: линейными списками и деревьями.
Самый простой способ соединить, или связать, множество элементов – это расположить их линейно в списке. В этом случае каждый элемент содержит только одну ссылку, связывающую его со следующим элементом списка. Пусть тип link описан следующим образом:
type
link = ^node;
node = record
info:string;
next:link
end;
var s,p:link;
Мы можем создать с помощью этого типа список, изображенный на рис. 5:
Рис. 1 Список элементов типа link
Переменная – ссылка s указывает на первую компоненту списка. По-видимому, самое простое действие, которое можно выполнить со списком, показанным на рисунке 1, это вставить в его начало некоторый элемент (рис. 2).
new(p);
p^.info:='Петров';
p^.next:=s;
s:=p;
Рис. 2 Вставить элемент в начало списка
Операция включения элемента в начало списка определяет, как можно построить список: начиная с пустого списка, последовательно добавляя элементы в его начало.
Пусть число связываемых элементов равно n. Тогда формировать список можно следующим образом:
s:=nil; {начали с пустого списка}
while n>0 do
begin
new(p); p^.next:=s;
read(p^.info);
s:=p;n:=n-1 end;