
- •1.Язык Object Pascal. Алфавит языка. Операторы. Выражения. Структура программы.
- •2. Простые типы данных. Преобразование типов. Приведение типов. Составной оператор.
- •3. Управляющие конструкции языка.
- •3.1 Безусловные конструкции
- •3.2 Условные конструкции.
- •3.3 Циклические конструкции.
- •4. Комментарии в крограммах. Директивы.
- •5. Структурные типы данных.
- •5.3 Записи.
- •6. Подрограммы.
- •6.1 Процедуры и функции. Состав. Синтаксис.
- •6.2 Список формальных параметров.
- •6.3 Параметры-значения. Параметры-переменные. Параметры-константы. Нетипизированные параметры.
- •6.4 Передача массивов в подпрограммы. Параметры типа открытый массив.
- •6.5 Локальные переменные. Область видимости. Время жизни.
- •6.6 Рекурсия. Виды рекурсии. Опережающее описание подпрограмм.
- •6.7 Процедурные типы
- •7. Модули
- •7.1 Назначение. Синтаксис.
- •8. Файлы
- •8.1 Общий алгоритм работы с файлом.
- •8.2 Подпрограммы для открытия файла.
- •8.3 Типизированные файлы. Режимы доступа к файлу. Переменная Filemode.
- •8.4 Обработка ошибок ввода-вывода.
- •8.5 Нетипизированные файлы.
- •8.6 Текстовые файлы
- •9. Динамическая память и указатели.
- •9.1 Указатель. Синтаксис. Допустимые операции.
- •9.2 Типизированные и нетипизированные указатели.
- •9.3 Операция резадресации (разыменования) указателя. Операции взятия адреса. Пустой указатель.
- •10. Типы с управляемым временем жизни.
- •10.1 Длинные строки. Механизм подсчета ссылок.
- •12.2 Динамические массивы.
- •11. Динамические структуры данных. Связные списки. Вставка и удаление узлов.
- •11.1 Односвязные списки. Структура. Особенности обработки.
- •11.2 Двусвязные списки
- •11.3 Кольцевые списки.
- •12. Отладка программ.
- •12.1 Виды программных ошибок.
- •12.2 Отладка программ.
- •12.3 Принципы контрактного программирования.
- •12.4 Принципы модульного тестирования.
- •12.5 Трассировка. Точки контрольного останова
- •12.6 Ведение протокола программы.
- •12.8 Основные принципы оформления исходного кода программы.
- •13. Алгоритмы
- •13.1 Алгоритм последовательного поиска.
- •13.2 Алгоритм бинарного поиска.
- •13.3 Алгоритм интерполирующего поиска.
- •13.4 Алгоритм вставки элемента в отсортированный массив.
- •13.5 Алгоритм поиска минимального (максимального) элемента массива.
- •13.6 Алгоритм пузырьковой сортировки.
- •13.7 Алгоритм сортировки перемешиванием.
- •13.8 Алгоритм сортировки прочесыванием.
- •13.9 Алгоритм сортировки методом выбора.
- •13.10 Алгоритм сортировки методом вставок.
- •13.11 Алгоритм сортировки методом Шелла.
- •13.12 Алгоритм сортировки слиянием.
- •13.13 Алгорим быстрой сортировки (сортировка Хоара).
10. Типы с управляемым временем жизни.
Некоторые типы Object Pascal, по сути, являются указателями, хотя программист никогда для переменных этих типов не выделяет и не освобождает память. Более того не используется операция разадресации указателей. Вся работа по выделению и освобождению памяти для переменных этих типов производится автоматически. Операция разадресации также производится автоматически. К этим типам относятся:
•длинные строки (AnsiString),
•динамические массивы
•интерфейсы.
Общим для всех этих типов является то, что после того как программа перестает использовать переменную (например после выхода из подпрограммы) любого из этих типов, то память занятая переменной автоматически освобождается. Таким образом, в отличие от обычных динамических переменных, при работе с переменными с управляемым временем жизни нет необходимости (или почти нет) следить за своевременным освобождением памяти, что существенно повышает надежность программ.
10.1 Длинные строки. Механизм подсчета ссылок.
В стандартном Паскале используются только короткие строки String[N]. В памяти такой строке выделяется N+1 байт, первый байт содержит текущую длину строки, а сами символы располагаются начиная со 2-го по счету байта. Поскольку для длины строки в этом случае отводится один байт, максимальная длина короткой строки не может превышать 255 символов. Для объявления короткой строки максимальной длины может использоваться стандартный тип ShortString (эквивалент String[255]).
Директива компилятора {$H} определяет какой тип строки будет подразумеваться под типом String. По умолчанию {$H+} String – длинная строка. При установке {$H-} под типом String будет подразумеваться тип ShortString.
В Windows используются только нуль-терминальные строки, представляющие собой цепочки символов, ограниченные символом #0. Максимальная длина такой строки лимитируется только доступной памятью и может быть очень большой.
Тип AnsiString, сочетает в себе удобства обоих типов. При работе с этим типом память выделяется по мере надобности (динамически) и ограничена имеющейся в распоряжении программы доступной памятью.
Механизм работы с памятью для длинных строк следующий. При объявлении длинной строки S: компилятор выделит для переменной 4 байта, достаточные для размещения указателя на область памяти где будут находится данные строки и установит значение указателя в nil. При присваивании строке значения «Hello» программа (а не компилятор!) определит длину цепочки символов «Hello», обратится к ядру операционной системы с требованием выделить для нее участок памяти длиной 5+5=10 байт, поместит в переменную S указатель на выделенную область памяти. Далее программа скопирует в эту область памяти данные строки, т. е. «Hello», завершив ее терминальным нулем, рисунок 5. Кроме этого, как показано на рисунке 5, заполняется два поля, находящиеся по отрицательному
смещению: поле счётчика ссылок и поле длины строки.
Такое размещение на этапе выполнения программы называется динамическим, в то время как размещение на этапе компиляции – статическим. При работе с длинными строками используется механизм подсчета ссылок. С его помощью реализуется «кэширование» памяти: при выполнении оператора
S2:=S;
память для размещения значения переменной S2 не выделяется, в переменную S2 помещается содержимое указателя S, а счетчик ссылок в связанной с ним памяти увеличивается на единицу, рисунок 6.
Таким образом, оба указателя будут ссылаться на одну и ту же область памяти, счетчик ссылок которой будет содержать значение 2. При выполнении оператора
SS:= S+’ World’;
счетчик ссылок уменьшается на единицу, выделяется новая область памяти длиной 11 + 5 = 16 байт, указатель на эту область помещается в S2, а в саму память переписывается цепочка символов «Hello World», терминальный ноль и содержащий единицу счетчик ссылок. Теперь переменные S и S2 будут ссылаться на разные участки памяти, счетчики ссылок которых будут содержать по единице, рисунок 7 Выделенная для размещения строки String область памяти освобождается, если ее счетчик ссылок стал равен нулю. Для строк-констант счетчик ссылок равен -1. Это сделано для предотвращения попыток удаления таких строк.
При работе со строкой как с массивом (доступ к символам строки по индексу) полезно предварительно выделить необходимое количество памяти. Это можно сделать с помощью процедуры SetLength, которая имеет следующий синтаксис:
procedure SetLength(var S; NewLength: Integer)
гдеS – строка AnsiString;
NewLength – новая длина строки.
Как уже говорилось в лабораторной работе «Типизированные файлы», существует проблема записи в файл ссылочных типов данных, таких как AnsiString и динамических массивов. Ниже показан пример решения этой проблемы. Программа, приведённая в листинге 6, демонстрирует запись и чтение строк переменной длины (AnsiString) из не типизированного файла. Запись происходит в два этапа:
•запись длины строки (переменная типа Integer);
•запись содержимого строки (объём записываемых данных зависит от реальной длины строки).
Чтение строк происходит в том же порядке. Сначала считывается длина строки, затем выделяется память достаточная для хранения строки указанного размера (SetLength). Производится чтение данных, объем которых равен длине считываемой строки.