- •Часть I. Работа в среде
- •Глава 1. Интегрированная среда
- •1.1. Окно просмотра результатов Output
- •1.2. Окно просмотра переменных Watch
- •1.3. Структура меню
- •1.3.1. Пункт File (работа с файлами)
- •1.3.2. Пункт Edit (работа с редактором)
- •1.3.3. Пункт Run (запуск на выполнение)
- •1.3.4. Пункт Compile (компиляция)
- •1.3.5. Пункт Options (установка параметров системы)
- •1.3.6. Пункт Debug (установки отладчика)
- •1.3.7. Пункт Break/Watch (точки останова/обзор)
- •1.4. Интерактивная справка
- •Глава 2. Настройка системы
- •2.1. Система настройки среды программирования
- •2.2. Принятые в системе расширения имен файлов
- •Часть II. Язык турбо паскаль
- •Глава 3. Построение программ
- •3.1. Алфавит языка и зарезервированные слова
- •3.2. Общая структура программ
- •3.3. Комментарии и ключи компиляции
- •3.4. Условная компиляция программ
- •Глава 4. Введение в систему типов языка
- •4.1. Простые типы языка
- •4.1.1. Целочисленные типы
- •4.1.2. Вещественные числа
- •4.1.3. Логический тип
- •4.1.4. Символьный тип
- •4.1.5. Строковый тип
- •4.1.6. Адресный тип
- •4.1.7. Перечислимые типы
- •4.1.8. Ограниченные типы (диапазоны)
- •4.2. Сложные типы языка
- •Глава 5. Константы и переменные
- •5.1. Простые константы
- •5.2. Переменные
- •5.2.1. Совмещение адресов директивой absolute
- •5.2.2. Переменные со стартовым значением или типизированные константы
- •5.3. Операция присваивания и совместимость типов и значений
- •5.4.Изменение (приведение) типов и значений
- •Глава 6. Управляющие структуры языка
- •6.1. Простой и составной операторы
- •6.2. Условный оператор (if...Then...Else)
- •If Условие then Оператор1 else Оператор2;
- •6.3. Оператор варианта (case)
- •6.4. Оператор цикла с предусловием (while)
- •6.6. Оператор цикла с параметром (for...Do)
- •6.7. Оператор безусловного перехода Goto
- •6.8. Операторы Exit и Halt
- •6.9. Процедуры и функции
- •6.9.1. Параметры. Глобальные и локальные описания
- •6.9.2. Опережающее описание процедур и функций
- •6.9.3. Объявление внешних процедур
- •6.9.4. Процедуры и функции как параметры
- •6.9.5. Переменные-процедуры и функции
- •6.9.6. Специальные приемы программирования
- •6.10. Модули. Структура модулей
- •6.11. Особенности работы с модулями
- •6.12. Система библиотечных модулей языка
- •Часть III. Средства языка турбо паскаль
- •Глава 7. Массивы, записи и множества в деталях
- •7.1. Массивы (Array) и работа с ними
- •7.2. Тип «запись» (Record) и оператор присоединения With
- •7.3. Тип «множество» (Set). Операции с множествами
- •Глава 8. Обработка символов и строк
- •8.1. Символьный и строковый типы (Char и String)
- •8.2. Операции над символами
- •8.3. Операции над строками
- •8.3.1. Редактирование строк
- •8.3.2. Преобразование строк
- •8.3.2.1. Процедура Str( X [: Width [: dec ] ]; var s : String)
- •Глава 9. Математические возможности Турбо Паскаля
- •9.1. Базовые операции
- •9.2. Битовая арифметика
- •9.3. Логические вычисления и операции отношения
- •9.4. Математические процедуры и функции
- •9.4.1. Обсуждение математических функций языка
- •9.4.2. Генераторы случайных чисел
- •9.4.3. Оптимизация сложения и вычитания
- •9.5. Использование математического сопроцессора 80x87
- •Глава 10. Код программы, данные, адреса
- •10.2. Распределение памяти при выполнении программ
- •10.3. Анализ расположения кода и областей данных программы
- •10.5. Средства для работы с адресами
- •10.5.1. Определение адреса переменных
- •10.5.2. Создание адреса функцией Ptr
- •10.5.3. Определение размеров типов и переменных
- •Глава 11. Ссылки, динамические переменные и структуры
- •11.1. Ссылочные переменные
- •11.2. Операция разыменования
- •11.3. Организация памяти области кучи
- •11.4. Управление размерами области кучи и стека
- •11.5. Процедуры управления кучей
- •11.5.1. Размещение динамических переменных.
- •11.5.2. Освобождение динамических переменных.
- •11.5.3. Управление состоянием кучи.
- •11.5.4. Анализ состояния кучи.
- •11.5.5. Более детальный анализ состояния кучи
- •11.5.6. Обработка ошибок распределения памяти
- •11.6. Ссылки, работающие не с кучей
- •11.7. Как организовать структуры, большие чем 64к?
- •11.8. Практический пример построения стека
- •Глава 12. Ввод-вывод данных и файловая система
- •12.1. Понятие логического файла
- •12.2. Физические файлы в ms-dos
- •12.3. Понятие буфера ввода-вывода
- •12.4. Файловые типы Турбо Паскаля
- •12.5. Общие процедуры для работы с файлами
- •12.5.1. Связывание файлов
- •12.5.2. Открытие файлов
- •12.5.3. Закрытие файлов
- •12.5.4. Переименование файлов
- •12.5.5. Удаление файлов
- •12.5.6. Анализ состояния файлов
- •12.6. Текстовые файлы
- •12.6.1. Текст-ориентированные процедуры и функции
- •12.6.2. Операции ввода-вывода в текстовые файлы
- •123 1.23 [Клавиша ввода]
- •123 [Клавиша ввода] 1.23 [Клавиша ввода]
- •12.7. Типизированные файлы и операции ввода-вывода
- •12.8. Бестиповые файлы и операции ввода-вывода
- •12.9. Последовательный и прямой доступ к файлам
- •12.9.1. Опрос размеров файлов и позиции в них
- •12.9.2. Позиционирование в файлах
- •12.9.3. Усечение файлов
- •12.10. Процедуры для работы с каталогами
- •12.11. Обработка ошибок ввода-вывода
- •12.11.1. Функция ioResult
- •12.11.2. Примеры обработки ошибок ввода-вывода
- •12.11.3. Сводка номеров ошибок ввода-вывода
- •Глава 13. Объектно-ориентированное программирование
- •13.1. Определения объектов
- •13.2. Область действия полей объекта и параметр Self
- •13.3. Наследование
- •13.4. Присваивание объектов
- •13.5. Полиморфизм
- •13.5.1. Статические методы
- •13.5.2. Виртуальные методы
- •13.5.3. Выбор вида метода
- •13.6. Динамические объекты
- •13.6.1. Создание динамических объектов
- •13.6.2. Освобождение объектов. Деструкторы
- •13.6.3. Обработка ошибок при работе с динамическими объектами
- •13.7. Функции TypeOf и SizeOf
- •13.8. Задание стартовых значений объектам
- •13.9. Модули, экспортирующие объекты
- •Глава 14. Специальные средства языка
- •14.1. Работа с командной строкой. Функции ParamCount и ParamStr
- •14.2. Доступ к памяти пэвм. Массивы Mem, MemW, MemL
- •14.3. Доступ к портам ввода-вывода. Массивы Port и PortW
- •14.4. Процедура заполнения FillChar
- •14.5. Процедура перемещения данных Move
- •14.6. Функции обработки машинных слов Lo, Hi и Swap
- •14.7. Вставки машинного кода в программе
- •14.7.1. Оператор inline
- •14.7.2. Процедуры с директивой inline
- •14.8. Процедура завершения и обработка ошибок программ
- •14.8.1. Оператор RunError
- •14.8.2. Сводка номеров фатальных ошибок
- •Часть IV. Специальные библиотеки языка
- •Глава 15. Модуль crt
- •15.1. Вывод специальных символов
- •15.2. Модификация операторов Read, ReadLn
- •15.3. Системные переменные модуля crt
- •15.3.1. Переменные управления выводом на дисплей
- •15.3.2. Переменные управления работой клавиатуры
- •15.3.3. Переменная TextAttr
- •15.4. Процедуры и функции модуля crt
- •15.4.1. Работа с экраном в целом
- •15.4.2. Позиционирование курсора
- •15.4.3. Работа со строками
- •15.4.4. Настройка цвета
- •15.4.5. Подача звуковых сигналов
- •15.4.6. Использование встроенного таймера
- •15.4.7. Опрос клавиатуры
- •If KeyPressed then Действие ;
- •15.4.8. Переназначение стандартных файлов
- •Глава 16. Модуль dos
- •16.1. Опрос и установка параметров ms-dos
- •16.1.1. Управление параметрами break и verify 16.1.1.1.
- •16.1.2. Опрос системных переменных ms-dos
- •16.2. Работа с часами и календарем
- •16.2.1. Опрос и назначение даты
- •16.2.3. Работа с датой создания файлов
- •16.3. Анализ ресурсов дисков
- •16.4. Работа с каталогами и файлами
- •16.4.1. Типы и константы модуля dos для работы с файлами
- •16.4.2. Переменная DosError
- •16.4.3. Процедуры поиска файлов на диске
- •16.4.4. Работа с атрибутами файлов
- •16.4.5. Анализ имен файлов
- •16.5. Работа с прерываниями ms-dos
- •16.5.1. Чтение и перестановка адресов подпрограмм прерываний
- •16.5.2. Вызов прерывания процедурой Intr
- •16.5.3. Процедура MsDos
- •6.6. Организация субпроцессов и резидентных программ
- •16.6.1. Программирование субпроцессов
- •Глава 17. Модуль Printer
- •7.1. Содержимое модуля Printer
- •17.2. Низкоуровневые средства работы с принтером
- •17.3. Работа с двумя принтерами одновременно
- •Глава 18. Модуль Overlay
- •18.1. Оверлейное построение программ
- •18.2. Правила оформления оверлейных программ
- •18.3. Инициализация работы оверлеев
- •18.3.1. Включение администратора оверлеев
- •18.3.2. Анализ результата инициализации
- •18.3.3. Размещение оверлейного файла в ems-памяти
- •18.4. Управление оверлейным буфером
- •18.4.1. Опрос размера буфера
- •18.4.2. Установка размера буфера
- •18.4.3. Принудительная очистка буфера
- •18.5. Оптимизация работы оверлеев
- •18.5.1. Установка размера области испытаний
- •18.5.2. Подсчет вызовов оверлеев
- •18.6. Предопределенные переменные для работы с оверлеями
- •18.7. Включение оверлеев в ехе-файлы
- •Глава 19. Модуль Graph
- •19.1. Файлы bgi и содержимое модуля Graph
- •19.2. Управление графическими режимами
- •19.2.1. Инициализация и закрытие графического режима
- •19.2.2. Обработка ошибок инициализации
- •19.2.3. Классификация и анализ графических режимов
- •19.2.4. Очистка экрана и переключение режимов
- •19.2.5. Управление режимом вывода отрезков на экран
- •19.3. Системы координат и «текущий указатель»
- •19.3.1. Координаты устройства и мировые координаты
- •19.3.2. Управление «текущим указателем»
- •19.4. Рисование графических примитивов и фигур
- •19.4.1. Линии и их стили
- •1100110011001100 — Всего 16 разрядов.
- •19.4.2. Коэффициент сжатия изображения
- •19.4.3. Окружности, эллипсы и дуги
- •19.4.4. Построение прямоугольников и ломаных
- •19.5. Управление цветами и шаблонами заливки (заполнения)
- •19.5.1. Немного о цветах
- •19.5.2. Задание типа заливки
- •19.5.3. Заливка областей изображения
- •19.5.4. Опрос и установка цветов пера и фона
- •19.5.5. Управление палитрой
- •19.6. Битовые графические операции
- •19.6.1. Битовые операции
- •19.6.2. Работа с фрагментами изображений
- •19.7. Управление видеостраницами
- •19.8. Графические окна
- •19.9. Вывод текста
- •19.9.1. Выбор шрифта и стиля
- •19.9.2. Предварительная загрузка и регистрация шрифтов
- •19.9.3. Непосредственный вывод строк
- •19.9.4. Размер букв и его масштабирование
- •19.9.5. Опрос стиля и ориентации шрифтов
- •19.10. Включение шрифтов и драйверов в ехе-файл
- •19.11. Подключение новых драйверов
- •19.12. Один полезный совет
- •Часть V. Практические
- •Глава 20. Профессиональная работа с
- •20.1. Программный опрос режимов текстового дисплея
- •20.2. Организация доступа к видеопамяти
- •20.3. Запоминание окон экрана и их восстановление
- •20.3.1. Общие принципы работы с окном
- •20.3.2. Модуль Win
- •20.4. Работа с образом экрана на диске
- •20.5. Крупные надписи на экране
- •20.6. Управление формой курсора
- •Глава 21. Как осуществить полный доступ к клавиатуре
- •21.1. Как организовать опрос алфавитно-цифровой клавиатуры
- •21.2. Опрос клавиши в регистре Ctrl
- •21.3. Опрос расширенных кодов и функциональных клавиш
- •21.4. Опрос служебных клавиш
- •21.5. Анализ клавиш регистров и их состояния
- •21.6. Скэн-коды клавиатуры и работа с ними
- •21.7. Эффект обратной записи в буфер ввода
- •Глава 22. Работа с оперативной
- •22.1. Многобитовое и многоплоскостное озув
- •22.2. Карта дисплейной памяти
- •22.3. Вывод текста на графический экран
- •22.4. Работа с графическими образами на диске
- •Приложение 2 Ключи и директивы компилятора
- •Ключи режимов компиляции
- •Директивы с параметрами
- •Приложение 3
- •Файл tpc.Cfg
- •Приложение 4 Список утилит пакета Турбо Паскаль (версия 5.5)
- •Программа администрирования библиотек
- •Утилита поиска текстов grep
- •Утилита преобразования двоичных файлов binobj
- •Приложение 5
- •Основные команды перемещения курсора
- •Расширенный набор команд перемещения курсора
- •Команды вставки и удаления
- •Команды работы с блоками
- •Поиск и замена
- •Прочие команды
- •Приложение 6
- •If False then Оператор;
- •Приложение 7
- •Глава 6. Управляющие структуры языка
- •Глава 8. Обработка символов и строк
- •Глава 9. Математические возможности Турбо Паскаля
- •Глава 16. Модуль dos
- •Глава 17. Модуль Printer
- •Глава 18. Модуль Overlay
- •Глава 19. Модуль Graph
- •Глава 20. Профессиональная работа с текстовыми изображениями
- •Глава 21. Как осуществить полный доступ к клавиатуре
- •Глава 22. Работа с оперативной памятью видеоадаптеров
- •Литература
- •Оглавление
- •Часть I. Работа в среде программирования
- •Часть II. Язык турбо паскаль
- •Часть III. Средства языка турбо паскаль
- •Часть IV. Специальные библиотеки языка
- •Часть V. Практические приемы работы с пэвм
13.2. Область действия полей объекта и параметр Self
Область действия (domain) полей данных объекта неявно распространяется на тела процедур и функций, реализующих методы этого объекта. В примере на рис. 13.1 метод Init (процедура) работает с полями Line и Col объекта типа ObjPos, обращение к которым не требует указания имени объекта. Можно сказать, что внутри методов объекта действует неявный оператор WITH. Следствием этого является то, что формальные параметры метода (если присутствуют) не могут совпадать по имени ни с одним из полей данных соответствующего объекта. {273}
Мы не раз подчеркивали, что внешне объекты очень похожи на записи. Так же, как и записи, они могут явно записываться в теле оператора WITH :
VAR
ObjPosVar : ObjPos; { экземпляр объекта }
...
with ObjPosVar do { оператор присоединения }
begin
Init( 1,1); { имя экземпляра опущено }
...
Init( GetLine+1, GetCol+1 );
...
end; { with }
Всякий раз, когда вызывается метод какого-либо объекта, в него, кроме фактических параметров, передается невидимый параметр Self («свой», «внутренний»). Он указывает, какому объекту принадлежит метод. Так, метод Init из примера на рис. 13.1 воспринимается компилятором так, как если бы он был описан следующим образом:
PROCEDURE ObjPos.Init( init_line, init_col : Word );
BEGIN
Self.Line := init_line; { метод задания номера строки }
Self.Col := init_col { метод задания номера столбца }
END;
Компилятор автоматически обрабатывает параметр Self, поэтому не стоит использовать его явно. Исключением является случай, когда идентификаторы начинают «конфликтовать» в пределах методов. На рис. 13.2 показано, как, используя в методе объекта параметр Self, разрешить конфликт между полями самого объекта и формального параметра (записи).
TYPE PosRec = RECORD { запись } Line, Col : Word; { номера строки и столбца } END; ObjPos = OBJECT { объект } Line, Col : Word; { номера строки и столбца } PROCEDURE Init2( Pos : PosRec ); { метод } END; |
Рис. 13.2 {274}
PROCEDURE ObjPos.Init2( Pos : PosRec ); BEGIN with Pos do begin { присоединение для записи Pos } Self.Line:= Line; { Self развязывает одинаковые имена} Self.Col := Col end {with} END; |
Рис. 13.2 (окончание)
13.3. Наследование
При помощи объекта типа ObjPos (см. рис. 13.1) определяется положение какого-либо символа в тексте на дисплее, но сам символ в нем не определен. Объявим объект с именем ObjSym, добавляющий символ и выполняющий определенные действия с ним (рис. 13.3).
USES CRT; { в примере используется системный модуль CRT } TYPE ObjSym = OBJECT Line : Word; { номер строки с Sym } Col : Word; { номер столбца с Sym } Sym : Char; { поле-значение символа } PROCEDURE Init(init_line,init_col : Word; init_sym : Char); FUNCTION GetLine : Word; { опрос Line } FUNCTION GetCol : Word { опрос Col } PROCEDURE Print { вывод Sym } END; PROCEDURE ObjSym.Init; { инициализация полей объекта } BEGIN Line := init_line; { метод задания номера строки } Col := init_col; { метод задания номера столбца } Sym := init_sym { задание значения символа } END; FUNCTION ObjSym.GetLine : Word; BEGIN GetLine := Line { метод опроса номера строки } END; |
Рис. 13.3 {275}
FUNCTION ObjSym.GetCol : Word; BEGIN GetCol := Col { метод опроса номера столбца } END; PROCEDURE ObjSym.Print; BEGIN CRT.GotoXY(Col,Line); { процедура из библиотеки CRT } Write( Sym ) { вывод символа в позиции } END; |
Рис. 13.3 (окончание)
Обратите внимание на то, что в задании нового объекта использовались поля данных и два метода GetLine и GetCol, идентичные полям и методам ранее описанного объекта ObjPos. Метод Init переписан заново, а поле Sym и, по сути, метод Print просто добавлены. Можно сказать, что более сложный объект, описывающий символ в тексте, унаследовал свойства и методы объекта-позиции. Методология ООП строится как раз на построении такого ряда объектов, в котором можно было бы проследить развитие и наследование свойств от простых структур к сложным.
Синтаксически наследование выражается следующим образом. В случае определения типа объекта, как производного от уже существующего, имя прародительского объекта заключается в круглые скобки после служебного слова OBJECT:
TYPE
ИмяОбъектаНаследника = OBJECT( ИмяОбъектаПрародителя )
НовыеПоляОбъектаНаследника;
НовыеМетодыОбъектаНаследника;
END;
Пример на рис. 13.3 по правилам ООП и Турбо Паскаля должен выглядеть, как показано на рис. 13.4 (на нем не показаны, но используются определения, введенные ранее на рис. 13.1).
Тип «наследник» иногда называется производным типом, а тип, от которого производится наследование («прародитель») — прародительским типом. Таким образом, отличие объекта от записи состоит не только в объединении полей и методов «под одной крышей», но и в способности объектов к наследованию. Поля и методы прародителя могут появляться в телах методов наследника, как если бы они были объявлены явно. На рис. 13.4 это иллюстрируется методом Init, который для инициализации полей {276}
USES CRT; { в примере используется системный модуль CRT } {*3десь должны быть определения, введенные на рис.13.1*} TYPE ObjSym = OBJECT( ObjPos ) { объявление наследования } Sym : Char; { поле-значение символа } PROCEDURE Init(init_line, init_col : Word; init_sym : Char ); PROCEDURE Print { метод вывода символа } END; PROCEDURE ObjSym.Init; BEGIN ObjPos.Init( init_line, init_col ); {задание позиции } Sym := init_sym { задание значения символа } END; PROCEDURE ObjSym.Print; BEGIN CRT.GotoXY(Col, Line); { процедура из библиотеки CRT } Write( Sym ) { вывод символа в позиции } END; |
Рис. 13.4
Line и Col, «по наследству» перешедших к объекту ObjSym, пользуется наследуемой процедурой ObjPos.Init.
Продолжая ряд наследования, можно ввести объект, описывающий символ совместно с его цветовым атрибутом. Для этого достаточно описать объект, производный от ObjSym и добавляющий поле данных для атрибута и методы его назначения или опроса. Такой объект будет третьим уровнем наследования, если считать от базового объекта ObjPos. Но можно объявить и объект того же уровня наследования по отношению к ObjPos, что и ObjSym. Определим, к примеру, объект «подстрока» (он пригодится в последующих примерах). Для задания подстроки надо указать координаты ее начала номер строки и столбца) и само содержимое подстроки, которое содержит в себе указание на ее длину. Можно создать объект типа ObjString, описывающий подстроку, как производный от объекта-позиции (рис. 13.5).
Процесс наследования является транзитивным: если тип объекта TypeB наследуется от типа объекта TypeA, а тип TypeC наследуется от TypeB, то тип объекта TypeC также считается наследником типа TypeA. Таким образом, можно получить иерархию объектов, связан-{277}
TYPE ObjString = OBJECT( ObjPos ) SubSt : String; { поле-значение подстроки } PROCEDURE Init( init_line, init_col:Word; init_ss:String ); PROCEDURE Print { вывод SubSt в позиции } END; PROCEDURE ObjString.Init; { инициализация полей объекта } BEGIN ObjPos.Init( init_tine, init_col ); {задание позиции } SubSt := init_ss { задание значения подстроки } END; PROCEDURE ObjString.Print; BEGIN CRT.GotoXY(Col, Line); { процедура из библиотеки CRT } Write( SubSt ) { печать подстроки в позиции } END; |
Рис. 13.5
ных «родственными» отношениями. Как правило, основная часть работы по написанию объектно-ориентированных программ состоит в построении именно иерархий объектов.
При наследовании полей в производных типах уже нельзя объявлять их идентификаторы, определенные в одном из прародительских типов. Однако на методы это ограничение не распространяется. Производный объект может переопределять любой из методов, наследуемый от своих прародителей. Если описание метода в производном типе вводит тот же идентификатор для метода, что и описание метода в прародительском типе, то в этом случае ко всем последующим потомкам переходит переопределенный метод (пока он не будет заново переопределен). Следует отметить, что во всех прародительских типах действуют те методы, которые были определены изначально именно для них.
Несколько слов о «хорошем тоне» ООП. В случае, если в производном типе описывается новая процедура инициализации, в ней обычно вначале вызывается процедура инициализации непосредственного прародителя. Так удобно поступать еще и потому, что это самый естественный способ проинициализировать наследуемые поля предназначенным для этого методом. {278}
