Содержание Введение ………………………………………………………………………………………..1 1. Основные принципы алгоритмизации и программирования …………………………….1 1.1. Основные понятия алгоритма……………………………………………………………..1 1.2. Языки и системы программирования. Методы программирования……………………5 2. Язык программирования Delphi………………………………………………………..….13 2.1. Основные составляющие среды программирования Delphi…………………………...13 2.2. Разработка программ с разветвлениями………………………………………………...23 2.3. Инструкции цикла. Массивы…………………………………………………………….25 2.4. Процедуры и функции……………………………………………………………………38 2.5 Модули…………………………………………………………………………………………..44 2.6 Символы и строки…………………………………………………………………………..46 2.7. Структурированные типы данных……………………………………………………..…52 2.8. Файлы…………………………………………………………………………………………...55 2.9. Классы и объекты………………………………………………………………………....60 Список использованных источников………………………………………………………....64
188
Embed
dep_ivs.pnzgu.rudep_ivs.pnzgu.ru/files/dep_ivs.pnzgu.ru/kurs_lekciy_op.docx · Web viewИзучение основ программирования является важным при
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Содержание
Введение ………………………………………………………………………………………..1
1. Основные принципы алгоритмизации и программирования …………………………….1
1.1. Основные понятия алгоритма……………………………………………………………..1
1.2. Языки и системы программирования. Методы программирования……………………5
2. Язык программирования Delphi………………………………………………………..….13
2.1. Основные составляющие среды программирования Delphi…………………………...13
2.2. Разработка программ с разветвлениями………………………………………………...23
2.9. Классы и объекты………………………………………………………………………....60
Список использованных источников………………………………………………………....64
Введение
Изучение основ программирования является важным при подготовке
квалифицированных технических специалистов. В конспекте лекций приводятся
принципы алгоритмизации и программирования, основы языка программирования Delphi.
При этом в ходе освоения студентами языка Delphi сложным для понимания нередко
оказывается материал по структурированным типам данных. Существует необходимость в
подробном описании таких структурированных типов данных языка Delphi, как строки,
множества, записи и файлы. Отдельный раздел посвящен объектно-ориентированному
программированию. О них и идет речь в лекционном материале – каждый из разделов
посвящен определенному типу данных; кроме теоретических сведений приведены
примеры программ.
Раздел 1. Основные принципы алгоритмизации и программирования
Тема 1.1. Основные понятия алгоритма
Понятие и свойства алгоритма. Способы записи алгоритмов. Виды алгоритмических
процессов.
Алгоритм – совокупность действий, приводящих к достижению результата за
конечное число шагов. Свойства алгоритмов:
1. Дискретность (от лат. discretus — разделенный,
прерывистый) – это разбиение алгоритма на ряд отдельных законченных действий
(шагов).
2. Детерминированность (от лат. determinate —
определенность, точность) - любое действие алгоритма должно быть строго и
недвусмысленно определено в каждом случае. Например, алгоритм проезда к другу, если
к остановке подходят автобусы разных маршрутов, то в алгоритме должен быть указан
конкретный номер маршрута 5. Кроме того, необходимо указать точное количество
остановок, которое надо проехать, скажем, три.
3. Конечность – каждое действие в отдельности и алгоритм в
целом должны иметь возможность завершения.
4. Массовость – один и тот же алгоритм можно использовать
с разными исходными данными.
5.Результативность – алгоритм должен приводить к достоверному решению.
Основная цель алгоритмизации – составление алгоритмов для ЭВМ с дальнейшим
решением задачи на ЭВМ. Существует несколько способов записи алгоритмов. На
практике наиболее распространены следующие формы представления алгоритмов:
1. словесная (запись на естественном языке);
2. псевдокоды (полуформализованные описания алгоритмов на условном
алгоритмическом языке, включающие в себя как элементы языка программирования, так и
фразы естественного языка, общепринятые математические обозначения и др.);
3. графическая (изображения из графических символов – блок-схема);
4. программная (тексты на языках программирования – код программы).
Словесный способ не имеет широкого распространения, так как такие описания:
строго не формализуемы; страдают многословностью записей; допускают
неоднозначность толкования отдельных предписаний.
Псевдокод занимает промежуточное место между естественным и формальным
языками. С одной стороны, он близок к обычному естественному языку, поэтому
алгоритмы могут на нем записываться и читаться как обычный текст. С другой стороны, в
псевдокоде используются некоторые формальные конструкции и математическая
символика, что приближает запись алгоритма к общепринятой математической записи. В
псевдокоде не приняты строгие синтаксические правила для записи команд, присущие
формальным языкам, что облегчает запись алгоритма на стадии его проектирования и дает
возможность использовать более широкий набор команд, рассчитанный на абстрактного
исполнителя. Однако в псевдокоде обычно имеются некоторые конструкции, присущие
формальным языкам, что облегчает переход от записи на псевдокоде к записи алгоритма
на формальном языке.
Виды алгоритмических процессов. Одним из свойств алгоритма является
дискретность – возможность расчленения процесса вычислений, предписанных
алгоритмом, на отдельные этапы, возможность выделения участков программы с
определенной структурой. Можно выделить и наглядно представить графически три
простейшие структуры: последовательность двух или более операций, выбор
направления, повторение. Любой вычислительный процесс может быть представлен как
комбинация этих элементарных алгоритмических структур. Вычислительные процессы,
выполняемые на ЭВМ по заданной программе, можно разделить на три основных вида:
линейные, разветвляющиеся, циклические.
Линейным принято называть вычислительный процесс, в котором операции
выполняются последовательно, в порядке их записи.
Вычислительный процесс называется разветвляющимся, если для его реализации
предусмотрено несколько направлений (ветвей).
Циклическими называются алгоритмы, содержащие циклы. Цикл – это многократно
повторяемый участок алгоритма. Все три вида алгоритмов реализуются в блок-схеме
названными выше типами блоков. К примеру, в линейном алгоритме могут
присутствовать все блоки, кроме блока условия. В разветвляющемся и циклическом
алгоритмах могут быть использованы все названные виды блоков, но обязательным
является блок условия. Внутри блока условия записывается условие, про которое можно
однозначно ответить, истинно оно или ложно. Если условие истинно, то выполняются
действия, соответствующие стрелке "да", иначе стрелке "нет".
Понятие блок-схемы. Основные виды блоков. Блок-схема – это графическая
реализация алгоритма. Блок-схема представляет собой удобный и наглядный способ
записи алгоритма. Блок-схема состоит из функциональных блоков разной формы,
связанных между собой стрелками. В каждом блоке описывается одно или несколько
действий. Основные виды блоков представлены на рисунке 1.
Рисунок 1
Любая команда алгоритма записывается в блок-схеме в виде графического элемента
– блока и дополняется словесным описанием. Блоки в блок-схемах соединяются линиями
потока информации. Направление потока информации указывается стрелкой. В случае
потока информации сверху вниз и слева направо стрелку ставить не обязательно. Блоки в
блок-схеме имеют только один вход и один выход (за исключением логического блока –
блока с условием).
Тема 1.2. Языки и системы программирования. Методы программирования
1.2.1 Эволюция языков программирования. Классификация языков
программирования. Эволюция языков программирования. Классификация языков
программирования. Элементы языков программирования. Понятие системы
программирования. Исходный, объектный и загрузочный модули.
Методы программирования: структурный, модульный, объектный. Достоинства и
недостатки методов программирования. Общие принципы разработки программного
обеспечения. Жизненный цикл программного обеспечения.
Эволюция языков программирования В развитии инструментального программного
обеспечения (т.е. программного обеспечения, служащего для создания программных
средств в любой проблемной области) рассматривают пять поколений языков
программирования (ЯП). ЯП первого поколения представляли собой набор машинных
команд в двоичном (бинарном) или восьмеричном формате, который определялся
архитектурой конкретной ЭВМ. Каждый тип ЭВМ имел свой ЯП, программы на котором
были пригодны только для данного типа ЭВМ. Второе поколение ЯП характеризуется
созданием языков ассемблерного типа (ассемблеров, макроассемблеров), позволяющих
вместо двоичных и других форматов машинных команд использовать их мнемонические
символьные обозначения (имена). Являясь существенным шагом вперед, ассемблерные
языки все еще оставались машинно-зависимыми, а программист все также должен был
быть хорошо знаком с организацией и функционированием аппаратной среды
конкретного типа ЭВМ. При этом ассемблерные программы все так же затруднительны
для чтения, трудоемки при отладке и требуют больших усилий для переноса на другие
типы ЭВМ. Однако и сейчас ассемблерные языки используются при необходимости
разработки высокоэффективного программного обеспечения (минимального по объему и
с максимальной производительностью). Третье поколение ЯП начинается с появления в
1956 г. первого языка высокого уровня — Fortran, разработанного под руководством Дж.
Бэкуса в фирме IBM. За короткое время Fortran становится основным ЯП при решении
инженерно-технических и научных задач. Первоначально Fortran обладал весьма
ограниченными средствами обеспечения работы с символьной информацией и с системой
ввода-вывода. Однако постоянное развитие языка сделало его одним из самых
распространенных ЯВУ на ЭВМ всех классов — от микро- до суперЭВМ, а его версии
используются и для вычислительных средств нетрадиционной параллельной архитектуры.
Вскоре после языка Fortran появились такие ныне широко известные языки, как Algol,
Cobol, Basic, PL/1, Pascal, APL, ADA, C, Forth, Lisp, Modula и др. В настоящее время
насчитывается свыше 2000 различных языков высокого уровня. Языки четвертого
поколения носят ярко выраженный непроцедурный характер, определяемый тем, что
программы на таких языках описывают только что, а не как надо сделать. В программах
формируются скорее соотношения, а не последовательности шагов выполнения
алгоритмов. Типичными примерами непроцедурных языков являются языки,
используемые для задач искусственного интеллекта (например, Prolog, Langin). Так как
непроцедурные языки имеют минимальное число синтаксических правил, они
значительно более пригодны для применения непрофессионалами в области
программирования. Второй тенденцией развития ЯП четвертого поколения являются
объектно-ориентированные языки, базирующиеся на понятии программного объекта,
впервые использованного в языке Simula-67 и составившего впоследствии основу
известного языка SmallTalk. Программный объект состоит из структур данных и
алгоритмов, при этом каждый объект знает, как выполнять операции со своими
собственными данными. Третьим направлением развития языков четвертого поколения
можно считать языки запросов, позволяющих пользователю получать информацию из баз
данных. Языки запросов имеют свой особый синтаксис, который должен соблюдаться, как
и в традиционных ЯП третьего поколения, но при этом проще в использовании. Среди
языков запросов фактическим стандартом стал язык SQL (StructuredQueryLanguage). И,
наконец, четвертым направлением развития являются языки па- раллельного
программирования (модификация ЯВУ Fortran, языки Occam, SISAL, FP и др.), которые
ориентированы на создание программного обеспечения для вычислительных средств
параллельной архитектуры (многомашинные, мультипроцессорные среды и др.), в
отличие от языков третьего поколения, ориентированных на традиционную
однопроцессорную архитектуру. К интенсивно развивающемуся в настоящее время
пятому поколению относятся языки искусственного интеллекта, экспертных систем, баз
знаний (InterLisp, ExpertLisp, IQLisp, SAIL и др.), а также естественные языки, не
требующие освоения какого-либо специального синтаксиса (в настоящее время успешно
используются естественные ЯП с ограниченными возможностями — Clout, Q&A, HAL и
др.).
Основными элементами языков программирования являются: символы - неделимые
знаки;
элементарные конструкции – минимальные единицы, имеющие определенный смысл
(имена, числа, метки, директивы и т.д.); выражения – задают правило вычисления
некоторого значения; описания – сведения о данных; операторы – предписания о
выполнении конкретных действий.
Система программирования - программная система, предназначенная для
разработки программ на конкретном языке программирования. Система
программирования предоставляет пользователю специальные средства разработки
программ: транслятор, (специальный) редактор текстов программ, библиотеки
стандартных подпрограмм, программную документацию, отладчик и др.
Программа, подготовленная на языке высокого уровня, проходит несколько этапов:
1. этап. В текстовом редакторе пишется исходный код программы на алгоритмическом языке (source code) и сохраняется в файле с расширением *.pas.
2 этап. Трансляция, происходит преобразование исходного кода программы (source code) в объектный код(object code), т.е. происходит проверка синтаксиса написания операторов, и если ошибок в написании нет, осуществляется перевод на язык машинных кодов. Файл объектного кода имеет расширение *.obj;
Трансляторы предназначены для проверки правильности написания операторов и преобразования программ, написанных на языках программирования, в программы на машинном языке. Программа, подготовленная на каком-либо языке программирования, называется исходным модулем. В качестве входной информации трансляторы применяют исходные модули и формируют в результате своей работы объектные модули, являющиеся входной информацией для редактора связей. Объектный модуль содержит текст программы на машинном языке и дополнительную информацию, обеспечивающую настройку модуля по месту его загрузки и объединение этого модуля с другими независимо оттранслированными модулями в единую программу.
Трансляторы делятся на два класса: компиляторы (compiler) и интерпретаторы (interpreter). Компиляторы транслируют всю программу, но без ее выполнения. Интерпретаторы, в отличие от компиляторов, выполняют пооператорный перевод на машинный языки выполнение всей программы.
3. этап. Компоновка, когда происходит обработка объектного кода редактором связей, специальной программой осуществляющей построение загрузочного модуля (load module), пригодного к выполнению (рис 16.).
Компоновщик, или редактор связей - системная обрабатывающая программа, редактирующая и объединяющая объектные (ранее оттранслированные) модули в единые загрузочные, готовые к выполнению программные модули. Загрузочный модуль может быть помещен ОС в основную память и выполнен. К сожалению, устранение синтаксических ошибок еще не гарантирует того, что программа будет хотя бы запускаться, не говоря уже о правильности работы. Поэтому обязательным этапом процесса разработки является отладка. На этапе отладки, используя описание алгоритма, выполняется контроль правильности функционирования, как отдельных участков кода, так и всей программы в целом.
Методы программирования: структурный, модульный, объектный. Достоинства и
недостатки методов программирования. Общие принципы разработки программного
обеспечения. Жизненный цикл программного обеспечения. Модульное программирование
— это такой способ программирования, при котором вся программа разбивается на группу
компонентов, называемых модулями, причем каждый из них имеет свой контролируемый
размер, четкое назначение и детально проработанный интерфейс с внешней средой.
Единственная альтернатива модульности — монолитная программа. Определения модуля
и его примеры. Модуль — это совокупность команд, к которым можно обратиться по
имени. Модуль — это совокупность операторов программы, имеющая граничные
элементы и идентификатор (возможно агрегатный).
Функциональная спецификация модуля должна включать:
- синтаксическую спецификацию его входов, которая должна позволять построить
на используемом языке программирования синтаксически правильное обращение к нему;
- описание семантики функций, выполняемых модулем по каждому из его входов.
Разновидности модулей. Существуют три основные разновидности модулей:
1) "Маленькие" (функциональные) модули, реализующие, как правило, одну
какую-либо определенную функцию. Основным и простейшим модулем практически
во всех языках программирования является процедура или функция.
a)"Средние" (информационные) модули, реализующие, как правило, несколько
операций или функций над одной и той же структурой данных (информационным
объектом), которая считается неизвестной вне этого модуля.
2) "Большие” (логические) модули, объединяющие набор "средних" или "маленьких"
модулей. Примеры "больших" модулей в языках программирования:
Набор характеристик модуля предложен Майерсом. Он состоит из следующих
конструктивных характеристик:
1) размера модуля;
В модуле должно быть 7 (+/-2) конструкций (например, операторов для функций
или функций для пакета). Модуль (функция) не должен превышать 60 строк. В
результате его можно поместить на одну страницу распечатки или легко просмотреть на
экране монитора.
2) прочности (связности) модуля;
Существует гипотеза о глобальных данных, утверждающая, что глобальные данные
вредны и опасны. Идея глобальных данных дискредитирует себя так же, как и идея
оператора безусловного перехода goto. Локальность данных дает возможность легко
читать и понимать модули, а также легко удалять их из программы. Связность
(прочность) модуля (cohesion) — мера независимости его частей. Чем выше связность
модуля — тем лучше, тем больше связей по отношению к оставшейся части программы
он упрятывает в себе. Можно выделить типы связности, приведенные ниже.
Функциональная связность. Модуль с функциональной связностью реализует одну
какую-либо определенную функцию и не может быть разбит на 2 модуля с теми же
типами связностей.
Последовательная связность. Модуль с такой связностью может быть разбит на
последовательные части, выполняющие независимые функции, но совместно
реализующие единственную функцию. Например, один и тот же модуль может быть
использован сначала для оценки, а затем для обработки данных.
Информационная (коммуникативная) связность. Модуль с информационной
связностью — это модуль, который выполняет несколько операций или функций над
одной и той же структурой данных (информационным объектом), которая считается
неизвестной вне этого модуля. Эта информационная связность применяется для
реализации абстрактных типов данных.
3) сцепления модуля с другими модулями;
Сцепление (coupling) — мера относительной независимости модуля от других
модулей. Независимые модули могут быть модифицированы без переделки других
модулей. Чем слабее сцепление модуля, тем лучше. Рассмотрим различные типы
сцепления.
Независимые модули — это идеальный случай. Модули ничего не знают друг о
друге. Организовать взаимодействие таких модулей можно, зная их интерфейс и
соответствующим образом перенаправив выходные данные одного модуля на вход
другого. Достичь такого сцепления сложно, да и не нужно, поскольку сцепление по
данным (параметрическое сцепление) является достаточно хорошим.
Сцепление по данным (параметрическое) — это сцепление, когда данные
передаются модулю, как значения его параметров, либо как результат его обращения к
другому модулю для вычисления некоторой функции. Этот вид сцепления реализуется
в языках программирования при обращении к функциям (процедурам). Две
разновидности этого сцепления определяются характером данным.
-сцепление по простым элементам данных.
-сцепление по структуре данных. В этом случае оба модуля должны знать о
внутренней структуре данных.
4) рутинности (независимость от предыдущих обращений) модуля.
Рутинность — это независимость модуля от предыдущих обращений к нему (от
предыстории). Будем называть модуль рутинным, если результат его работы зависит
только от количества переданных параметров (а не от количества обращений).
Структурное программирование возникло как вариант решения проблемы
уменьшения сложности разработки программного обеспечения. Цель структурного
программирования - повышение надежности программ, обеспечение сопровождения и
модификации, облегчение и ускорение разработки. Методология структурного
программирования — подход, заключающийся в задании хорошей топологии императивных
программ, в том числе отказе от использования глобальных данных и оператора
безусловного перехода, разработке модулей с сильной связностью и обеспечении их
независимости от других модулей. Подход базируется на двух основных принципах:
последовательная декомпозиция алгоритма решения задачи сверху вниз, использование
структурного кодирования. Методы и концепции, лежащие в основе структурного
программирования.
Метод алгоритмической декомпозиции сверху вниз — заключается в пошаговой
детализации постановки задачи, начиная с наиболее общей задачи. Данный метод
обеспечивает хорошую структурированность. Метод поддерживается концепцией
алгоритма.
Метод модульной организации частей программы — заключается в разбиении
программы на специальные компоненты, называемые модулями. Метод поддерживается
концепцией модуля.
Метод структурного кодирования — заключается в использовании при кодировании
трех основных управляющих конструкций. Метки и оператор безусловного перехода
являются трудно отслеживаемыми связями, без которых мы хотим обойтись. Метод
поддерживается концепцией управления.
При использовании для построения программы метода, известного под названием
структурное программирование, программа конструируется иерархически - сверху вниз
(от главной программы к подпрограммам самого нижнего уровня), с употреблением на
каждом уровне только ограниченного набора управляющих структур: простых
последовательностей инструкций, циклов и некоторых видов условных разветвлений. При
последовательном проведении этого метода структуру результирующих алгоритмов легко
понимать, отлаживать и модифицировать.
Теорема о структурировании: Всякую правильную программу (т.е. программу с
одним входом и одним выходом без зацикливаний и недостижимых веток) можно
записать с использованием следующих логических структур - последовательность, выбора
и повторение цикла
Следствие 1: Всякую программу можно привести к форме без оператора goto.
Следствие 2: Любой алгоритм можно реализовать в языке, основанном на трех
Консольное приложение состоит из заголовка (правильного идентификатора) и
следующих разделов (структура консольного приложения): program p1;
{$APPTYPE CONSOLE}uses SysUtils;
Список подключаемых модулей начинается словом uses и содержит имена
модулей, содержимое которых может использовать данное консольное приложение.
Раздел меток начинается словом label, за которым следует список меток,
представляющих собой правильный идентификатор или целое число без знака.
Метки позволяют пометить любой оператор, чтобы на него можно было передать
управление из любого места программы.
Раздел констант начинается словом const, за которым идут конструкции вида <имя константы> = <значение>. Константами называют любые неизменяемые в процессе выполнения программы данные.
Раздел описания типов начинается словом type, за которым идут конструкции вида <имя типа> = <описание>, позволяющие программисту создавать собственные типы.
Раздел описания переменных начинается со слова var. Здесь должны быть указаны все переменные, используемые в разделе операторов программы, а также их тип: <имя переменной > : <тип>;
Раздел описания процедур и функций не выделяется специальным служебным словом, поскольку каждая подпрограмма имеет свой заголовок. Подпрограмма имеет структуру, подобную основной программе.
Раздел операторов начинается служебным словом begin и заканчивается словом
end, после которого ставится точка – признак конца программы. Раздел операторов
содержит последовательность действий, которую должен выполнить компьютер
const n = 10;
var t : boolean; x, i : integer; Данные, независимо от типа, имеют некоторое значение и в
программе предстают как константы или переменные. Данные, которые получили
значение в начале программы и по своей природе изменяться не могут, называются
константами. Константами, например, являются скорость света в вакууме и соотношение
единиц измерения (метр, сантиметр, ярд, фут, дюйм), которые имеют научно
обоснованные или традиционно принятые постоянные значения. Константы описываются
с помощью зарезервированного слова const. За ним идет список имен констант, каждому
из которых с помощью знака равенства присваивается значение. Одно присваивание
отделяется от другого с помощью точки с запятой. Тип константы распознается
компилятором автоматически, поэтому его не надо указывать при описании. Примеры
констант:
После такого описания для обращения к нужному значению достаточно указать лишь имя
соответствующей константы. Значение константы можно задавать и выражением. Эту
возможность удобно использовать для комплексного представления какого-либо понятия.
При объявлении константы можно указать ее тип. Такие константы называются
типизированными; их основное назначение — объявление константных значений
составных типов данных.
Простыми являются порядковые, вещественные типы и тип дата-время.
Порядковые типы характеризуются тем, что соответствующие им значения
образуют конечное упорядоченное множество и каждое значение имеет свой
порядковый номер. К порядковым типам относятся целые (табл. 1), логические
(табл.2), символьные, перечислимые типы и тип-диапазон. Для выражений
порядкового типа определены следующие функции:
ord(x) – возвращает порядковый номер значения данного выражения. Для
целых типов возвращает само значение x, для логического 0 или 1, для
символьного – значение в диапазоне от 0 до 255, для перечислимого – значение в
диапазоне от 0 до 65535. Для типа-дипазона результат зависит от свойств базового
порядкового типа.
pred(x) – возвращает значение, предшествующее значению данного выражения
x.
succ(x) – возвращает значение, следующее за значением данного выражения
x.
high(x) – возвращает максимальное возможное значение для аргумента x.
low(x) – возвращает минимальное возможное значение для аргумента x.
Таблица 1 - Целые типыТип Диапазон значений Размер (в байтах)
integer -2147483648..2147483647 4
cardinal 0..4294967295 4
shortint -128..127 1
smallint -32768..32767 2
longint -2147483648..2147483647 4
int64 -263..263-1 8
Byte 0..255 1
word 0..65535 2
longword 0..4294967295 4
Целые типы данных предназначены для представления целых чисел.
Наибольшая производительность процессора и операционной системы достигается
при использовании типов integer и cardinal.
К переменным целого типа можно применять операции целочисленного деления
div и mod. Если a и b – переменные целого типа, то
a div b – это целая часть частного от деления a на b;
a mod b – это остаток от деления a на b.
Например, 9 div 2 = 4 9 mod 2 = 1
При применении к данным целого типа операций
* div mod + –
полученный результат будет также целого типа. То же можно сказать и о
стандартных функциях abs и sqr. Операция деления / над целочисленными
операндами даёт результат вещественного типа. Если в арифметическом выражении
используются значения только какого-нибудь одного из целых типов, то результат
выражения будет иметь такой же тип. Если же в выражении используются значения
разных типов, то результат будет иметь тип integer. Для данных целого типа
определены процедуры:
inc(i, k) – увеличивает значение i на k единиц; если k не задано, то на 1;
dec(i, k) – уменьшает значение i на k единиц; если k не задано, то на 1.
2.2. Разработка программ с разветвлениями
В Delphi данные логического (булева) типа могут принимать одно из двух значений: true (истина) или false (ложь). Логические типы, определённые в Object Pascal: Таблица 2 - Логические типы
Тип Размер (в байтах)
Boolean 1
ByteBool 1
WordBool 2
LongBool 4
Основным логическим типом в Delphi 7 является Boolean. Остальные типы
нужны для совместимости с логическими данными, используемыми в Windows и
некоторых других системах программирования, например Visual C.
В логических выражениях можно использовать логические операции: not
(отрицание), and (логическое И), or (логическое ИЛИ), xor (логическое исключающее
ИЛИ). Результат применения этих операций к операндам логического типа
представлен в следующей таблице.
При записи логических выражений нужно помнить, что первой выполняется
операция not, затем and, потом or и xor. Операции отношения выполняются в
последнюю очередь.
Логические поразрядные операции предназначены для поразрядной обработки
целочисленных операндов, представленных в двоичном виде. Такими операциями
являются поразрядные отрицание (not), и (and), или (or), исключающее или (xor), а
также поразрядные сдвиг влево (shl) и сдвиг вправо (shr). Расмотрим пример. Пусть
переменные a и b типа byte имеют значения 3 и 5 соответственно. В двоичном
представлении эти числа будут иметь вид : 00000011 и 00000101. Вычислим a xor
b. Операция xor будет применяться поразрядно, т.е. к каждой паре чисел, стоящих в
одинаковых позициях. Результат можно определить при помощи приведённой выше
таблицы, если мысленно заменить 0 словом false, а 1 – словом true. Получим
00000110 = 6 (10). Операции shl и shr сдвигают значение переменной влево или
вправо на указанное количество битов (например a shl 1 – сдвиг влево на 1 бит).
При этом начальные или конечные биты теряются, а вновь появившиеся биты
содержат нулевые значения. Это эквивалентно умножению на 2 в степени, равной
количеству разрядов смещения.
Вещественные типы не являются порядковыми. Поскольку данные в компьютере хранятся в виде двоичных кодов, то действительные числа, в отличие от целых, представляются приближённо, хотя и с большой степенью точности.
: Таблица 3 - Вещественные типыТип Диапазон значений Размер (в байтах)
Параметр S – это строка типа string или динамический массив. Функция Copy
возвращает подстроку строки S, начинающуюся с символа с номером Index и
содержащую Count символов.
procedure Delete(var S : string; Index, Count : integer);
Удаляет из S подстроку, начинающуюся с символа с номером Index и содержащую
Count символов.
procedure Insert(Substr : string; S : string; Index : integer);
Вставляет строку Substr в S, начиная с символа с номером Index.
function Length(S : string): integer;
Возвращает число символов в строке S.
function Pos(Substr, S : string): integer;
Возвращает позицию (индекс) первого вхождения подстроки Substr в строку S. Если
Substr нет в S, то возвращается 0.
procedure SetLength(var S; NewLength : integer);
Параметр S является строкой или динамическим массивом. Процедура устанавливает
новую длину NewLength строки S. Если строка имеет тип ShortString, то значение
параметра NewLength должно находиться в диапазоне 0..255. Для длинных строк
значение параметра NewLength ограничено лишь размерами доступной памяти
компьютера. При увеличении длины строки старые значения, находившиеся там,
сохраняются, а во вновь добавленных позициях находятся неопределённые значения.
function StringOfChar(Ch : char; Count : integer): string;
Создаёт строку, состоящую из Count раз повторяющегося символа Ch.
function Trim(const S : string): string;
Удаляет из строки S начальные и завершающие пробелы и управляющие символы.
Строковые выражения.
Над строками определены операции отношения. Строки сравниваются по кодам
символов. Напомним, что для консольных приложений используется кодировка
ASCII, а для оконных – ANSI. При сравнении двух строк последовательно
сравниваются коды символов, стоящих в одинаковых позициях. Символы в строках
просматриваются слева направо. Если в очередной паре оказываются различные
символы, то большей считается та строка, символ которой имеет больший код. На
этом сравнение прекращается. Если сравниваются строки разной длины, причём
одна строка совпадает с началом другой, то большей будет более длинная строка.
Например,
муха < слон
слон < слоник
2 > 123
Кроме операций отношения над строками определена операция сцепления
(конкатенации), которая обозначается знаком + . Например,
Object + Pascal = Object Pascal
Строки разных типов могут смешиваться в одном выражении, переменным
одного строкового типа можно присваивать значения другого строкового типа.
Компилятор при этом осуществляет автоматическое приведение типов. Если
переменной типа ShortString присваивается в качестве значения строка, длина
которой больше 255, то лишние символы отбрасываются.
Для ввода символьных строк необходимо использовать процедуру readln, а не
read. Это объясняется тем, что в конце каждой символьной строки, вводимой с
клавиатуры, стоит так называемый разделитель строк EOLN (end of line) –
последовательность кодов #13(CR – перевод каретки) и #10(LF – переход на начало
строки). Разделитель строк вставляется во вводимый текст при нажатии на клавишу
Enter. Процедура readln считывает все символы, расположенные до разделителя
строк, а затем и символы разделителя строк (#13 и #10), которые являются
управляющими и переводят курсор дисплея в начало следующей строки.
Пример . Используя стандартные функции для строк, получить из строки
'grammofon' строку fonogramma.
var t, s : string; i, j : integer; Комментарий
begin
s:='grammofon';
i:=pos('o', s); i = 6
t:=copy(s, 1, i-1); t = gramm
delete(s, 1, i); s = fon
j:=length(s); j = 3
s:= s + t + 'a'; s = fongramma
insert('o', s, j+1); s = fonogramma
writeln(s); readln
end.
Преобразование строк в числовые типы и обратно.
Задача преобразования строк в числовые типы и обратно для консольных
приложений не актуальна, так как процедуры read, readln, write, writeln выполняют
эти преобразования автоматически. Основная область применения этих подпрограмм
– оконные приложения, при создании которых программист сам должен
предусматривать преобразование типов.
procedure Str(x; var s:string);
Преобразует целое или действительное значение x в строку s (параметр x может
иметь указание формата вывода).
procedure Val(s:string; var v; var code:integer);
Преобразует строку s в целую или вещественную переменную v. Параметр code
равен нулю, если преобразование прошло успешно, в противном случае он равен
номер позиции в строке s, где обнаружен ошибочный символ. Например: если
s:='95'; , то в результате выполнения val(s,x,d); x = 95, d=0. Если s=a4, то x=0, d=1.
function StrToInt(s:string):integer;
Возвращает целое число, изображением которого является строка s.
function StrToFloat(s:string):extended;
Возвращает вещественное число, изображением которого является строка s.
function IntToStr(n:integer):string;
Возвращает строку, являющуюся изображением целого числа n.
function FloatToStr(n:extended):string;
Возвращает строку, являющуюся изображением вещественного числа n.
function FloatToStrF(n:extended; format; k, m:integer):string; – строка, являющаяся
изображением вещественного n в различных форматах;
при вызове функции указываются:
format – формат (способ изображения);
k – общее количество цифр;
m – количество цифр после десятичной точки.
Значениями параметра format могут быть следующие константы:
ffFixed – число представляется в формате с фиксированной десятичной точкой.
ffExponent – научный формат (экспоненциальная форма записи).
ffGeneral – общий цифровой формат.
ffNumber – аналогичен ffFixed, но в изображении числа используется разделитель
групп разрядов.
ffCurrency – денежный формат.
Например: если x=3.587 и s:=floattostrf(x, ffFixed, 7, 3); , то s = 3,587 (используется
десятичная запятая).
2.7. Структурированные типы данных.
Запись – это структура данных, состоящая из фиксированного числа
компонентов, называемых полями записи. Компоненты (поля) записи могут быть
различного типа.
Описание типа запись:
имя типа record список полей end;
Здесь имя типа – правильный идентификатор. Список полей представляет собой
последовательность разделов записи, между которыми ставится точка с запятой.
Каждый раздел записи состоит из одного или нескольких идентификаторов полей,
отделённых друг от друга запятыми. За идентификатором ставится двоеточие и
описание типа поля.
Пример. Запись в телефонной книге может быть представлена в виде следующей
структуры данных:
type tel = record
number : integer;
fio : string[40];
adr : string[60]
end;
var m, v : tel;
Обращение к значению поля осуществляется с помощью идентификатора переменной
записи и идентификатора поля, разделённых точкой. Например:
m.number; m.fio; m.adr;
Поля записи используются в программе как обычные переменные соответствующего
типа. Например, можно написать
m.numberm.number 1; или m.fio[1]<>Ф
Допускается применение оператора присваивания к записи в целом. Например,
vm; После выполнения этого оператора значения полей записи v станут равны
значениям соответствующих полей записи m. Логические операции сравнения для
записей не определены. Тип запись нельзя использовать для описания типа
функции.
Обращение к полям записи имеет несколько громоздкий вид. Для решения этой
проблемы в языке Паскаль предназначен оператор присоединения with , который
имеет следующий формат:
with переменная типа запись do оператор;
Один раз указав переменную типа запись в операторе with , можно далее работать
с именами полей без указания перед идентификатором поля имени записи.
Например:
with m do begin number1364; fioПетров end;
Пример 50. Описать тип point для точки на плоскости со следующими полями:
буква, обозначающая точку, координата x, координата y. Даны две точки. Найти
длину отрезка, соединяющего эти две точки.
type point = record
name : 'A' .. 'Z';
x : real;
y : real
end;
var a, b : point; ab : real;
begin
readln(a.name, a.x, a.y);
with b do
readln(name, x, y);
ab:=sqrt(sqr(b.x – a.x) + sqr(b.y – a.y));
writeln(a.name, b.name, ' = ', ab:5:2); readln
end.
Множественный тип представляет собой конечный набор значений некоторого
базового типа. В качестве базового типа может использоваться любой порядковый
тип, кроме word, integer, longint, int64.
Описание множественного типа имеет вид:
<имя типа > = set of <базовый тип>;
Например:
type mn1 = set of A . . Z;
mn2 = set of 1 . . 5;
Значениями переменных множественного типа являются любые подмножества
базового множества. Для задания множества используется конструктор множества,
представляющий собой список элементов базового множества, разделённых запятыми
и обрамлённый квадратными скобками.
Пример.
type digitChar set of 0 .. 9;
digit set of 0 .. 9;
var s1, s2 : digitChar; s3, s4, s5 : digit;
begin
s1[1, 2, 3]; s2[3, 2, 1];
s3[0..3, 6]; s4[4, 5]; s5[3..9]
end.
[] – пустое множество. Над множествами определены операции:
– пересечение множеств.
s3s4=[]; s3s5=[3, 6];
– объединение множеств.
s3+s4=[0 .. 6];
– – разность множеств.
s5 – s4=[3, 6 .. 9];
= – проверка эквивалентности множеств, возвращает true, если множества
эквивалентны.
s1=s2
<> – проверка неэквивалентности.
<= – проверка вложения.
s4<=s5 результат true.
in – проверка принадлежности.
7 in s5 результат true.
Стандартные процедуры для работы с множествами:
include(s, i) – включает элемент i базового типа в множество s.
exclude(s, i) – исключает элемент i из множества s.
Использование множеств позволяет сделать программы более эффективными за
счёт уменьшения количества различных проверок.
Пример . Используя метод Решето Эратосфена напечатать все простые числа из
диапазона 1..30.
Суть метода – вычёркиваем из исходного множества [1..30] те числа, которые
не являются простыми.
var n : set of 1..30; k, s : integer;
begin
n:=[1..30];
for s:=2 to 15 do
if s in n then
for k:=s+1 to 30 do
if k mod s=0 then exclude(n, k);
for s:=1 to 30 do
if s in n then write(s:3);
readln
end.
Программа работает следующим образом. Вначале s=2. Это значение
принадлежит n, поэтому, начиная с числа 3, вычёркиваем все числа, кратные 2.
Теперь s=3. Это значение принадлежит n, поэтому, начиная с числа 4,
вычёркиваем все числа, кратные 3. Теперь s=4. Это значение уже вычеркнуто из n.
Переходим к s=5 и так далее. Вывод на экран элементов полученного множества
осуществляем следующим образом: перебираем все элементы базового множества и
отбираем для печати те из них, которые принадлежат n.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
2.8. Файлы
Object Pascal располагает средствами создания и обработки файлов различных
типов. Доступ к файлу осуществляется с помощью переменных файлового типа. В
Object Pascal существует три файловых типа:
TextFile – текстовый файл, представляющий собой набор символьных
строк переменной длины;
File of < тип > – типизированный файл, представляющий собой набор
данных указанного типа;
File – нетипизированный файл, представляющий собой набор
неструктурированных данных.
Примеры описания файловых переменных:
var f1: textfile; f2: file of integer; f3: file of char; f4: file;
Здесь f1 – текстовый файл, f2 и f3 – типизированные файлы, f4 – нетипизированный
файл.
Стандартные подпрограммы для доступа к файлам.
Работа с файлами заключается в записи и считывании информации. Для того
чтобы указать, с каким элементом будет производиться очередная операция чтения
или записи, существует понятие указателя на доступный элемент файла. После
каждого чтения или записи указатель перемещается на следующий элемент файла.
Перед использованием файловой переменной она должна быть связана с
внешним файлом ( файлом на диске) с помощью вызова процедуры
AssignFile(< файловая переменная>, < имя файла>);
здесь <файловая переменная> – имя переменной файлового типа, объявленной в
программе; <имя файла> – символьная строка, содержащая имя файла. Если файл
находится в одной папке с обрабатывающей его программой, то достаточно указать
только имя файла, в противном случае надо указать полный путь к файлу,
например:
c:\files\z1.txt
Когда связь с внешним файлом установлена, его можно открыть для ввода или
вывода информации. Существующий файл можно открыть с помощью процедуры
Reset(<файловая переменная>);
Процедура reset открывает существующий внешний файл, имя которого было
связано с файловой переменной. Если внешний файл с указанным именем
отсутствует, то возникает ошибка периода выполнения программы. Если файл уже
открыт, то он сначала закрывается, а затем открывается вновь. Файловый указатель
устанавливается на элемент файла с порядковым номером 0.
Текстовый файл, открытый процедурой reset, доступен только для чтения. Для
типизированных и нетипизированных файлов, открытых процедурой reset,
допускается выполнять операции чтения и записи в файл.
Новый файл можно создать и открыть для записи с помощью процедуры
Rewrite(<файловая переменная>);
Процедура rewrite создаёт новый файл, имя которого связано с файловой
переменной. Если файл с указанным именем уже существует, то он удаляется и на
его месте создаётся новый пустой файл. Текущая позиция в файле устанавливается
на начало файла, т.е. указатель будет указывать на элемент с порядковым номером
0.
Если процедура rewrite открывает текстовый файл, то он становится доступным
только для записи. Для типизированных и нетипизированных файлов, открытых
процедурой rewrite, допускается выполнять операции чтения и записи в файл.
Текстовый файл может быть открыт процедурой
Append(<файловая переменная>);
Процедура append открывает уже существующий внешний файл, связанный с
файловой переменной, для добавления новой информации. Если файла с указанным
именем не существует, то возникает ошибка. Если файл уже открыт, то он сначала
закрывается, а затем открывается заново. Указатель будет указывать на конец
файла. В результате обращения к append текстовый файл становится доступным
только для записи.
Когда программа завершает обработку файла, он должен быть закрыт с
помощью стандартной процедуры
CloseFile(<файловая переменная>);
Процедура closefile закрывает открытый файл. При этом обеспечивается
сохранение в файле всех новых записей и регистрация файла в папке. Процедура
closefile не разрывает связь файла с файловой переменной, поэтому файл можно
открыть снова без повторного использования процедуры assignfile.
Текстовые файлы.
Текстовый файл представляет собой последовательность символов,
сгруппированных в строки произвольной длины, где каждая строка заканчивается
маркером конца строки – EOLN (end of line), состоящим из двух символов: CR=#13 и
LF=#10. Заканчивается файл символом конца файла EOF (end of file, код #26).
Чтение данных из произвольного текстового файла можно осуществить с
помощью процедур read и readln. При этом в списке их параметров первой должна
стоять соответствующая файловая переменная. Например, процедура read(f, x, y, z);
осуществляет чтение из файла, связанного с файловой переменной f, значения
переменных x, y, z. Процедура readln(f, a);
прочитает из файла, связанного с переменной f, значение переменной a и перейдёт
в этом файле к следующей строке.
Вывод данных в текстовый файл производится процедурами write и writeln, у
которых первой в списке параметров указана соответствующая файловая переменная.
Например, процедура write(f, s = , s) осуществляет запись в файл, связанный с
переменной f, символьной строки s = и значения переменной s. Процедура
writeln(f) запишет в файл, связанный с переменной f, пустую строку.
При работе с текстовыми файлами используются логические функции
eof(<файловая переменная>) и eoln(<файловая переменная >). Функция eof
возвращает значение true, если достигнут конец файла, и false в противном случае.
Функция eoln возвращает значение true, если достигнут конец строки в текстовом
файле, и false в противном случае.
Текстовый файл можно создать в среде Delphi, выбрав в меню команду
File�New�Text. В открывшемся окне нужно набрать содержимое текстового файла и
сохранить файл с помощью команды File�Save. Текстовый файл можно также
создать программным способом. Рассмотрим несколько возможных вариантов
программы для создания текстового файла.
Типизированные файлы.
Типизированный файл содержит элементы одного типа. Тип элементов может
быть любым, кроме файлового. Создать и просмотреть такой файл при помощи
текстового редактора как текстовый файл нельзя. Поэтому обработка таких файлов
должна осуществляться программным путём. Напомним, что описание файловой
переменной, соответствующей типизированному файлу имеет вид:
var <имя файловой переменной> : file of <тип>;
Для чтения данных из типизированного файла применяется процедура read.
Список ввода процедуры read должен содержать переменные того же типа, что и
элементы файла. Для записи в типизированный файл используется процедура write,
список вывода которой должен содержать переменные того же типа, что и
элементы файла. Процедуры readln и writeln для типизированных файлов не
применяются.
Доступ к текстовым файлам возможен только последовательно, то есть, когда
элемент считывается или записывается, указатель файла перемещается к
следующему по порядку элементу файла. К типизированным файлам можно
организовать прямой доступ с помощью стандартной процедуры
procedure seek( var f; n:longint);
которая перемещает файловый указатель в типизированном файле, связанном с
файловой переменной f, на элемент с номером n. Нумерация элементов в файле
начинается с нуля. Для определения текущей позиции в файле используется
функция
function filepos( var f):longint;
Для определения размера файла используется функция
function filesize( var f):integer;
Например, для установки файлового указателя на последний элемент файла f
достаточно записать
seek(f, filesize(f)–1);
на первый элемент файла
seek(f, 0);
вернуться на один элемент назад
seek(f, filepos(f)–1);
Применение процедур assignfile и closefile для типизированных файлов не
отличается от текстовых файлов. Процедура reset, в отличие от текстовых файлов,
допускает для типизированных файлов не только чтение, но и запись в файл.
Процедура rewrite, в отличие от текстовых файлов, допускает не только запись, но
и чтение из файла. Процедура append и функция eoln для типизированных файлов
не работают.
Нетипизированные файлы.
С точки зрения Object Pascal, нетипизированный файл представляет собой
последовательность байтов, содержащих данные произвольного типа и структуры.
Основное назначение нетипизированных файлов – обеспечение совместимости с
любыми типами файлов и организация высокоскоростного обмена данными между
внешними запоминающими устройствами и оперативной памятью. Описание
нетипизированного файла f имеет вид:
var f : file;
В процедурах reset и rewrite для нетипизированных файлов указывается
дополнительный параметр RecSize, чтобы задать размер записи, используемой при
передаче файла:
procedure reset (var f : file {; RecSize : word});
procedure rewrite (var f : file {; RecSize : word});
Если параметр RecSize не указан, то принимаемая по умолчанию длина
записи равна 128 байтам. Длина записи измеряется в байтах и может быть задана
произвольным целым числом – от 1 байта до 2 Гбайт. Если задать длину записи,
кратную 512 байт, то это позволит выполнять операции чтения-записи для
нетипизированного файла с максимальной скоростью.
За исключением процедур read и write для нетипизированных файлов
можно использовать все стандартные процедуры, которые допускается использовать
для типизированных файлов. Вместо процедур read и write используются
процедуры blockread и blockwrite, позволяющие пересылать данные с высокой
скоростью:
procedure blockread( var f : file; var buf; count : integer; {var at : integer});
procedure blockwrite( var f : file; var buf; count : integer; {var at : integer});
Здесь f – имя файловой переменной, связанной с нетипизированным файлом,
buf – переменная, в которую будут помещаться данные при чтении из файла или из
которой будут извлекаться данные при записи в файл. Count – параметр целого
типа, указывающий, какое количество записей необходимо прочитать или записать
за одно обращение к файлу. Переменная buf должна иметь длину равную
count�RecSize байт. Необязательный параметр at содержит количество реально
прочитанных или записанных записей.
2.9. Классы и объекты
Объектно-ориентированное программирование (ООП) – это методика разработки
программ, в основе которой лежит понятие объекта, как некоторой структуры,
описывающей объект реального мира, его поведение. Задача, решаемая с
использованием методики ООП, описывается в терминах объектов и операций над
ними, а программа при таком подходе представляет собой набор объектов и связей
между ними.
Строго говоря, для разработки оконного приложения в Delphi на базе
компонентов, предоставляемых средой разработки, знание концепции ООП не
является необходимым. Однако материал данной главы будет весьма полезен для
более глубокого понимания того, как программа взаимодействует с компонентами,
что и почему Delphi добавляет в текст программы.
Язык Object Pascal, поддерживая концепцию объектно-ориентированного
программирования, даёт возможность определять классы. Описание типа class
напоминает описание типа record (запись), но тип class кроме описания полей
данных содержит ещё методы (процедуры и функции).
Объект в Object Pascal – это конкретный экземпляр класса. Переменная-объект
понимается как динамическая структура, то есть содержит не данные, а ссылку на
данные объекта. Выделение памяти под эти данные осуществляется при помощи
специального метода – конструктора (constructor).
Пример объявления простого класса:
type tPerson = class
fname : string[15];
faddress : string[45];
fage : byte;
procedure show;
end;
var boy1 : tPerson;
В основе объектно-ориентированного программирования лежат три основных
принципа: инкапсуляция, наследование и полиморфизм.
Инкапсуляцией называется объединение в классе данных и подпрограмм для их
обработки. Данные содержатся в полях класса, а процедуры и функции называются
методами. В соответствии с правилами объектно-ориентированного
программирования прямой доступ к полям нежелателен. В связи с этим в Object
Pascal предусмотрены специальные конструкции, называемые свойствами, которые
осуществляют чтение или запись в поля при помощи вызова соответствующих
методов. Общепринятым является правило давать названия классам, начинающиеся с
буквы t. Например:
type tPerson = class;
Наследование означает, что класс может наследовать компоненты другого класса. Создать новый класс от некоторого класса-родителя можно следующим образом:
type tStudent = class(tPerson);
Принцип наследования заключается в том, что порождённый класс-потомок
автоматически наследует поля, методы и свойства своего родителя, и в тоже время
может дополнять их новыми.
В Object Pascal все классы являются потомками класса tObject. Этот класс не
включает в себя полей и свойств, зато его методы позволяют создавать,
поддерживать работу и удалять объекты. Если программист хочет создать класс,
являющийся непосредственным потомком класса tObject, то имя класса-родителя в
этом случае можно не указывать, т.е. следующие строки являются эквивалентными:
type tNewClass = class(tObject);
type tNewClass = class;
Использование принципа наследования в Delphi привело к созданию
разветвлённого дерева классов. В верхней части этого дерева находятся так
называемые абстрактные классы, для которых нельзя создать полноценные
работающие объекты. Но вместе с тем абстрактные классы являются
родоначальниками больших групп классов, для которых уже создаются реальные
объекты.
Полиморфизм позволяет использовать одинаковые имена для методов,
входящих в различные классы. Принцип полиморфизма обеспечивает в случае
обращения к одноимённым методам выполнение того из них, который соответствует
классу объекта.
В общем виде класс объявляется в разделе type следующим образом:
type < имя класса > = class(< имя класса-родителя >)
public
< описание общедоступных элементов >
published
< описание элементов, доступных в Инспекторе Объектов >
protected
< описание элементов, доступных в классах-потомках >
private
< описание элементов, доступных только в модуле >
end;
Секции public, published, protected, private могут содержать описания полей, методов,
свойств, событий.
Следующий пример иллюстрирует создание объекта типа tPerson, обращение к
его полям и методам.
type tPerson = class
private
fname : string[15];
faddress : string[45];
fage : byte;
public
procedure show;
end;
var boy1 : tPerson;
procedure tPerson.show;
begin
writeln('Surname?'); writeln(fname);
writeln('Address?'); writeln(faddress);
writeln('Age?'); writeln(fage);
end;
begin
boy1:=tPerson.Create; boy1.fname:='Ivanov';
boy1.faddress:='Kolzovskaja, 59-45';
boy1.fage:=16; boy1.show;
readln;
end.
После описания типа класса tPerson следует описание реализации методов. В
заголовке имя метода дополняется именем класса, к которому данный метод
относится (procedure tPerson.show;). В теле метода обращение к полям класса
происходит без указания имени класса. Создание объекта boy1 происходит в
результате применения конструктора Create к имени класса. Для того чтобы
обратиться к полю объекта, нужно написать имя объекта и имя поля, разделённые
точкой (boy1.fage). Аналогично записывается вызов метода объекта (boy1.show).
Классы, созданные разработчиками Delphi, образуют сложную иерархическую
2.9. Классы и объекты………………………………………………………………………....60
Список использованных источников………………………………………………………....64
Введение
Изучение основ программирования является важным при подготовке
квалифицированных технических специалистов. В конспекте лекций приводятся
принципы алгоритмизации и программирования, основы языка программирования Delphi.
При этом в ходе освоения студентами языка Delphi сложным для понимания нередко
оказывается материал по структурированным типам данных. Существует необходимость в
подробном описании таких структурированных типов данных языка Delphi, как строки,
множества, записи и файлы. Отдельный раздел посвящен объектно-ориентированному
программированию. О них и идет речь в лекционном материале – каждый из разделов
посвящен определенному типу данных; кроме теоретических сведений приведены
примеры программ.
Раздел 1. Основные принципы алгоритмизации и программирования
Тема 1.1. Основные понятия алгоритма
Понятие и свойства алгоритма. Способы записи алгоритмов. Виды алгоритмических
процессов.
Алгоритм – совокупность действий, приводящих к достижению результата за
конечное число шагов. Свойства алгоритмов:
6. Дискретность (от лат. discretus — разделенный,
прерывистый) – это разбиение алгоритма на ряд отдельных законченных действий
(шагов).
7. Детерминированность (от лат. determinate —
определенность, точность) - любое действие алгоритма должно быть строго и
недвусмысленно определено в каждом случае. Например, алгоритм проезда к другу, если
к остановке подходят автобусы разных маршрутов, то в алгоритме должен быть указан
конкретный номер маршрута 5. Кроме того, необходимо указать точное количество
остановок, которое надо проехать, скажем, три.
8. Конечность – каждое действие в отдельности и алгоритм в
целом должны иметь возможность завершения.
9. Массовость – один и тот же алгоритм можно использовать
с разными исходными данными.
10. Результативность – алгоритм должен приводить к
достоверному решению.
Основная цель алгоритмизации – составление алгоритмов для ЭВМ с дальнейшим
решением задачи на ЭВМ. Существует несколько способов записи алгоритмов. На
практике наиболее распространены следующие формы представления алгоритмов:
5. словесная (запись на естественном языке);
6. псевдокоды (полуформализованные описания алгоритмов на условном
алгоритмическом языке, включающие в себя как элементы языка программирования, так и
фразы естественного языка, общепринятые математические обозначения и др.);
7. графическая (изображения из графических символов – блок-схема);
8. программная (тексты на языках программирования – код программы).
Словесный способ не имеет широкого распространения, так как такие описания:
строго не формализуемы; страдают многословностью записей; допускают
неоднозначность толкования отдельных предписаний.
Псевдокод занимает промежуточное место между естественным и формальным
языками. С одной стороны, он близок к обычному естественному языку, поэтому
алгоритмы могут на нем записываться и читаться как обычный текст. С другой стороны, в
псевдокоде используются некоторые формальные конструкции и математическая
символика, что приближает запись алгоритма к общепринятой математической записи. В
псевдокоде не приняты строгие синтаксические правила для записи команд, присущие
формальным языкам, что облегчает запись алгоритма на стадии его проектирования и дает
возможность использовать более широкий набор команд, рассчитанный на абстрактного
исполнителя. Однако в псевдокоде обычно имеются некоторые конструкции, присущие
формальным языкам, что облегчает переход от записи на псевдокоде к записи алгоритма
на формальном языке.
Виды алгоритмических процессов. Одним из свойств алгоритма является
дискретность – возможность расчленения процесса вычислений, предписанных
алгоритмом, на отдельные этапы, возможность выделения участков программы с
определенной структурой. Можно выделить и наглядно представить графически три
простейшие структуры: последовательность двух или более операций, выбор
направления, повторение. Любой вычислительный процесс может быть представлен как
комбинация этих элементарных алгоритмических структур. Вычислительные процессы,
выполняемые на ЭВМ по заданной программе, можно разделить на три основных вида:
линейные, разветвляющиеся, циклические.
Линейным принято называть вычислительный процесс, в котором операции
выполняются последовательно, в порядке их записи.
Вычислительный процесс называется разветвляющимся, если для его реализации
предусмотрено несколько направлений (ветвей).
Циклическими называются алгоритмы, содержащие циклы. Цикл – это многократно
повторяемый участок алгоритма. Все три вида алгоритмов реализуются в блок-схеме
названными выше типами блоков. К примеру, в линейном алгоритме могут
присутствовать все блоки, кроме блока условия. В разветвляющемся и циклическом
алгоритмах могут быть использованы все названные виды блоков, но обязательным
является блок условия. Внутри блока условия записывается условие, про которое можно
однозначно ответить, истинно оно или ложно. Если условие истинно, то выполняются
действия, соответствующие стрелке "да", иначе стрелке "нет".
Понятие блок-схемы. Основные виды блоков. Блок-схема – это графическая
реализация алгоритма. Блок-схема представляет собой удобный и наглядный способ
записи алгоритма. Блок-схема состоит из функциональных блоков разной формы,
связанных между собой стрелками. В каждом блоке описывается одно или несколько
действий. Основные виды блоков представлены на рисунке 1.
Рисунок 1
Любая команда алгоритма записывается в блок-схеме в виде графического элемента
– блока и дополняется словесным описанием. Блоки в блок-схемах соединяются линиями
потока информации. Направление потока информации указывается стрелкой. В случае
потока информации сверху вниз и слева направо стрелку ставить не обязательно. Блоки в
блок-схеме имеют только один вход и один выход (за исключением логического блока –
блока с условием).
Тема 1.2. Языки и системы программирования. Методы программирования
1.2.1 Эволюция языков программирования. Классификация языков
программирования. Эволюция языков программирования. Классификация языков
программирования. Элементы языков программирования. Понятие системы
программирования. Исходный, объектный и загрузочный модули.
Методы программирования: структурный, модульный, объектный. Достоинства и
недостатки методов программирования. Общие принципы разработки программного
обеспечения. Жизненный цикл программного обеспечения.
Эволюция языков программирования В развитии инструментального программного
обеспечения (т.е. программного обеспечения, служащего для создания программных
средств в любой проблемной области) рассматривают пять поколений языков
программирования (ЯП). ЯП первого поколения представляли собой набор машинных
команд в двоичном (бинарном) или восьмеричном формате, который определялся
архитектурой конкретной ЭВМ. Каждый тип ЭВМ имел свой ЯП, программы на котором
были пригодны только для данного типа ЭВМ. Второе поколение ЯП характеризуется
созданием языков ассемблерного типа (ассемблеров, макроассемблеров), позволяющих
вместо двоичных и других форматов машинных команд использовать их мнемонические
символьные обозначения (имена). Являясь существенным шагом вперед, ассемблерные
языки все еще оставались машинно-зависимыми, а программист все также должен был
быть хорошо знаком с организацией и функционированием аппаратной среды
конкретного типа ЭВМ. При этом ассемблерные программы все так же затруднительны
для чтения, трудоемки при отладке и требуют больших усилий для переноса на другие
типы ЭВМ. Однако и сейчас ассемблерные языки используются при необходимости
разработки высокоэффективного программного обеспечения (минимального по объему и
с максимальной производительностью). Третье поколение ЯП начинается с появления в
1956 г. первого языка высокого уровня — Fortran, разработанного под руководством Дж.
Бэкуса в фирме IBM. За короткое время Fortran становится основным ЯП при решении
инженерно-технических и научных задач. Первоначально Fortran обладал весьма
ограниченными средствами обеспечения работы с символьной информацией и с системой
ввода-вывода. Однако постоянное развитие языка сделало его одним из самых
распространенных ЯВУ на ЭВМ всех классов — от микро- до суперЭВМ, а его версии
используются и для вычислительных средств нетрадиционной параллельной архитектуры.
Вскоре после языка Fortran появились такие ныне широко известные языки, как Algol,
Cobol, Basic, PL/1, Pascal, APL, ADA, C, Forth, Lisp, Modula и др. В настоящее время
насчитывается свыше 2000 различных языков высокого уровня. Языки четвертого
поколения носят ярко выраженный непроцедурный характер, определяемый тем, что
программы на таких языках описывают только что, а не как надо сделать. В программах
формируются скорее соотношения, а не последовательности шагов выполнения
алгоритмов. Типичными примерами непроцедурных языков являются языки,
используемые для задач искусственного интеллекта (например, Prolog, Langin). Так как
непроцедурные языки имеют минимальное число синтаксических правил, они
значительно более пригодны для применения непрофессионалами в области
программирования. Второй тенденцией развития ЯП четвертого поколения являются
объектно-ориентированные языки, базирующиеся на понятии программного объекта,
впервые использованного в языке Simula-67 и составившего впоследствии основу
известного языка SmallTalk. Программный объект состоит из структур данных и
алгоритмов, при этом каждый объект знает, как выполнять операции со своими
собственными данными. Третьим направлением развития языков четвертого поколения
можно считать языки запросов, позволяющих пользователю получать информацию из баз
данных. Языки запросов имеют свой особый синтаксис, который должен соблюдаться, как
и в традиционных ЯП третьего поколения, но при этом проще в использовании. Среди
языков запросов фактическим стандартом стал язык SQL (StructuredQueryLanguage). И,
наконец, четвертым направлением развития являются языки па- раллельного
программирования (модификация ЯВУ Fortran, языки Occam, SISAL, FP и др.), которые
ориентированы на создание программного обеспечения для вычислительных средств
параллельной архитектуры (многомашинные, мультипроцессорные среды и др.), в
отличие от языков третьего поколения, ориентированных на традиционную
однопроцессорную архитектуру. К интенсивно развивающемуся в настоящее время
пятому поколению относятся языки искусственного интеллекта, экспертных систем, баз
знаний (InterLisp, ExpertLisp, IQLisp, SAIL и др.), а также естественные языки, не
требующие освоения какого-либо специального синтаксиса (в настоящее время успешно
используются естественные ЯП с ограниченными возможностями — Clout, Q&A, HAL и
др.).
Основными элементами языков программирования являются: символы - неделимые
знаки;
элементарные конструкции – минимальные единицы, имеющие определенный смысл
(имена, числа, метки, директивы и т.д.); выражения – задают правило вычисления
некоторого значения; описания – сведения о данных; операторы – предписания о
выполнении конкретных действий.
Система программирования - программная система, предназначенная для
разработки программ на конкретном языке программирования. Система
программирования предоставляет пользователю специальные средства разработки
программ: транслятор, (специальный) редактор текстов программ, библиотеки
стандартных подпрограмм, программную документацию, отладчик и др.Программа, подготовленная на языке высокого уровня, проходит несколько
этапов:1. этап. В текстовом редакторе пишется исходный код программы на
алгоритмическом языке (source code) и сохраняется в файле с расширением *.pas.2 этап. Трансляция, происходит преобразование исходного кода программы
(source code) в объектный код(object code), т.е. происходит проверка синтаксиса написания операторов, и если ошибок в написании нет, осуществляется перевод на язык машинных кодов. Файл объектного кода имеет расширение *.obj;
Трансляторы предназначены для проверки правильности написания операторов и преобразования программ, написанных на языках программирования, в программы на машинном языке. Программа, подготовленная на каком-либо языке программирования, называется исходным модулем. В качестве входной информации трансляторы применяют исходные модули и формируют в результате своей работы объектные модули, являющиеся входной информацией для редактора связей. Объектный модуль содержит текст программы на машинном языке и дополнительную информацию, обеспечивающую настройку модуля по месту его загрузки и объединение этого модуля с другими независимо оттранслированными модулями в единую программу.
Трансляторы делятся на два класса: компиляторы (compiler) и интерпретаторы (interpreter). Компиляторы транслируют всю программу, но без ее выполнения. Интерпретаторы, в отличие от компиляторов, выполняют пооператорный перевод на машинный языки выполнение всей программы.
3. этап. Компоновка, когда происходит обработка объектного кода редактором связей, специальной программой осуществляющей построение загрузочного модуля (load module), пригодного к выполнению (рис 16.).
Компоновщик, или редактор связей - системная обрабатывающая программа, редактирующая и объединяющая объектные (ранее оттранслированные) модули в единые загрузочные, готовые к выполнению программные модули. Загрузочный модуль может быть помещен ОС в основную память и выполнен. К сожалению, устранение синтаксических ошибок еще не гарантирует того, что программа будет хотя бы запускаться, не говоря уже о правильности работы. Поэтому обязательным этапом процесса разработки является отладка. На этапе отладки, используя описание алгоритма, выполняется контроль правильности функционирования, как отдельных участков кода, так и всей программы в целом.
Методы программирования: структурный, модульный, объектный. Достоинства и
недостатки методов программирования. Общие принципы разработки программного
обеспечения. Жизненный цикл программного обеспечения. Модульное программирование
— это такой способ программирования, при котором вся программа разбивается на группу
компонентов, называемых модулями, причем каждый из них имеет свой контролируемый
размер, четкое назначение и детально проработанный интерфейс с внешней средой.
Единственная альтернатива модульности — монолитная программа. Определения модуля
и его примеры. Модуль — это совокупность команд, к которым можно обратиться по
имени. Модуль — это совокупность операторов программы, имеющая граничные
элементы и идентификатор (возможно агрегатный).
Функциональная спецификация модуля должна включать:
- синтаксическую спецификацию его входов, которая должна позволять построить
на используемом языке программирования синтаксически правильное обращение к нему;
- описание семантики функций, выполняемых модулем по каждому из его входов.
Разновидности модулей. Существуют три основные разновидности модулей:
3) "Маленькие" (функциональные) модули, реализующие, как правило, одну
какую-либо определенную функцию. Основным и простейшим модулем практически
во всех языках программирования является процедура или функция.
a)"Средние" (информационные) модули, реализующие, как правило, несколько
операций или функций над одной и той же структурой данных (информационным
объектом), которая считается неизвестной вне этого модуля.
4) "Большие” (логические) модули, объединяющие набор "средних" или "маленьких"
модулей. Примеры "больших" модулей в языках программирования:
Набор характеристик модуля предложен Майерсом. Он состоит из следующих
конструктивных характеристик:
5) размера модуля;
В модуле должно быть 7 (+/-2) конструкций (например, операторов для функций
или функций для пакета). Модуль (функция) не должен превышать 60 строк. В
результате его можно поместить на одну страницу распечатки или легко просмотреть на
экране монитора.
6) прочности (связности) модуля;
Существует гипотеза о глобальных данных, утверждающая, что глобальные данные
вредны и опасны. Идея глобальных данных дискредитирует себя так же, как и идея
оператора безусловного перехода goto. Локальность данных дает возможность легко
читать и понимать модули, а также легко удалять их из программы. Связность
(прочность) модуля (cohesion) — мера независимости его частей. Чем выше связность
модуля — тем лучше, тем больше связей по отношению к оставшейся части программы
он упрятывает в себе. Можно выделить типы связности, приведенные ниже.
Функциональная связность. Модуль с функциональной связностью реализует одну
какую-либо определенную функцию и не может быть разбит на 2 модуля с теми же
типами связностей.
Последовательная связность. Модуль с такой связностью может быть разбит на
последовательные части, выполняющие независимые функции, но совместно
реализующие единственную функцию. Например, один и тот же модуль может быть
использован сначала для оценки, а затем для обработки данных.
Информационная (коммуникативная) связность. Модуль с информационной
связностью — это модуль, который выполняет несколько операций или функций над
одной и той же структурой данных (информационным объектом), которая считается
неизвестной вне этого модуля. Эта информационная связность применяется для
реализации абстрактных типов данных.
7) сцепления модуля с другими модулями;
Сцепление (coupling) — мера относительной независимости модуля от других
модулей. Независимые модули могут быть модифицированы без переделки других
модулей. Чем слабее сцепление модуля, тем лучше. Рассмотрим различные типы
сцепления.
Независимые модули — это идеальный случай. Модули ничего не знают друг о
друге. Организовать взаимодействие таких модулей можно, зная их интерфейс и
соответствующим образом перенаправив выходные данные одного модуля на вход
другого. Достичь такого сцепления сложно, да и не нужно, поскольку сцепление по
данным (параметрическое сцепление) является достаточно хорошим.
Сцепление по данным (параметрическое) — это сцепление, когда данные
передаются модулю, как значения его параметров, либо как результат его обращения к
другому модулю для вычисления некоторой функции. Этот вид сцепления реализуется
в языках программирования при обращении к функциям (процедурам). Две
разновидности этого сцепления определяются характером данным.
-сцепление по простым элементам данных.
-сцепление по структуре данных. В этом случае оба модуля должны знать о
внутренней структуре данных.
8) рутинности (независимость от предыдущих обращений) модуля.
Рутинность — это независимость модуля от предыдущих обращений к нему (от
предыстории). Будем называть модуль рутинным, если результат его работы зависит
только от количества переданных параметров (а не от количества обращений).
Структурное программирование возникло как вариант решения проблемы
уменьшения сложности разработки программного обеспечения. Цель структурного
программирования - повышение надежности программ, обеспечение сопровождения и
модификации, облегчение и ускорение разработки. Методология структурного
программирования — подход, заключающийся в задании хорошей топологии императивных
программ, в том числе отказе от использования глобальных данных и оператора
безусловного перехода, разработке модулей с сильной связностью и обеспечении их
независимости от других модулей. Подход базируется на двух основных принципах:
последовательная декомпозиция алгоритма решения задачи сверху вниз, использование
структурного кодирования. Методы и концепции, лежащие в основе структурного
программирования.
Метод алгоритмической декомпозиции сверху вниз — заключается в пошаговой
детализации постановки задачи, начиная с наиболее общей задачи. Данный метод
обеспечивает хорошую структурированность. Метод поддерживается концепцией
алгоритма.
Метод модульной организации частей программы — заключается в разбиении
программы на специальные компоненты, называемые модулями. Метод поддерживается
концепцией модуля.
Метод структурного кодирования — заключается в использовании при кодировании
трех основных управляющих конструкций. Метки и оператор безусловного перехода
являются трудно отслеживаемыми связями, без которых мы хотим обойтись. Метод
поддерживается концепцией управления.
При использовании для построения программы метода, известного под названием
структурное программирование, программа конструируется иерархически - сверху вниз
(от главной программы к подпрограммам самого нижнего уровня), с употреблением на
каждом уровне только ограниченного набора управляющих структур: простых
последовательностей инструкций, циклов и некоторых видов условных разветвлений. При
последовательном проведении этого метода структуру результирующих алгоритмов легко
понимать, отлаживать и модифицировать.
Теорема о структурировании: Всякую правильную программу (т.е. программу с
одним входом и одним выходом без зацикливаний и недостижимых веток) можно
записать с использованием следующих логических структур - последовательность, выбора
и повторение цикла
Следствие 1: Всякую программу можно привести к форме без оператора goto.
Следствие 2: Любой алгоритм можно реализовать в языке, основанном на трех
Консольное приложение состоит из заголовка (правильного идентификатора) и
следующих разделов (структура консольного приложения): program p1;
{$APPTYPE CONSOLE}uses SysUtils;
Список подключаемых модулей начинается словом uses и содержит имена
модулей, содержимое которых может использовать данное консольное приложение.
Раздел меток начинается словом label, за которым следует список меток,
представляющих собой правильный идентификатор или целое число без знака.
Метки позволяют пометить любой оператор, чтобы на него можно было передать
управление из любого места программы.
Раздел констант начинается словом const, за которым идут конструкции вида <имя константы> = <значение>. Константами называют любые неизменяемые в процессе выполнения программы данные.
Раздел описания типов начинается словом type, за которым идут конструкции вида <имя типа> = <описание>, позволяющие программисту создавать собственные типы.
Раздел описания переменных начинается со слова var. Здесь должны быть указаны все переменные, используемые в разделе операторов программы, а также их тип: <имя переменной > : <тип>;
Раздел описания процедур и функций не выделяется специальным служебным словом, поскольку каждая подпрограмма имеет свой заголовок. Подпрограмма имеет структуру, подобную основной программе.
Раздел операторов начинается служебным словом begin и заканчивается словом
end, после которого ставится точка – признак конца программы. Раздел операторов
содержит последовательность действий, которую должен выполнить компьютер
const n = 10;
var t : boolean; x, i : integer; Данные, независимо от типа, имеют некоторое значение и в
программе предстают как константы или переменные. Данные, которые получили
значение в начале программы и по своей природе изменяться не могут, называются
константами. Константами, например, являются скорость света в вакууме и соотношение
единиц измерения (метр, сантиметр, ярд, фут, дюйм), которые имеют научно
обоснованные или традиционно принятые постоянные значения. Константы описываются
с помощью зарезервированного слова const. За ним идет список имен констант, каждому
из которых с помощью знака равенства присваивается значение. Одно присваивание
отделяется от другого с помощью точки с запятой. Тип константы распознается
компилятором автоматически, поэтому его не надо указывать при описании. Примеры
констант:
После такого описания для обращения к нужному значению достаточно указать лишь имя
соответствующей константы. Значение константы можно задавать и выражением. Эту
возможность удобно использовать для комплексного представления какого-либо понятия.
При объявлении константы можно указать ее тип. Такие константы называются
типизированными; их основное назначение — объявление константных значений
составных типов данных.
Простыми являются порядковые, вещественные типы и тип дата-время.
Порядковые типы характеризуются тем, что соответствующие им значения
образуют конечное упорядоченное множество и каждое значение имеет свой
порядковый номер. К порядковым типам относятся целые (табл. 1), логические
(табл.2), символьные, перечислимые типы и тип-диапазон. Для выражений
порядкового типа определены следующие функции:
ord(x) – возвращает порядковый номер значения данного выражения. Для
целых типов возвращает само значение x, для логического 0 или 1, для
символьного – значение в диапазоне от 0 до 255, для перечислимого – значение в
диапазоне от 0 до 65535. Для типа-дипазона результат зависит от свойств базового
порядкового типа.
pred(x) – возвращает значение, предшествующее значению данного выражения
x.
succ(x) – возвращает значение, следующее за значением данного выражения
x.
high(x) – возвращает максимальное возможное значение для аргумента x.
low(x) – возвращает минимальное возможное значение для аргумента x.
Таблица 1 - Целые типыТип Диапазон значений Размер (в байтах)
integer -2147483648..2147483647 4
cardinal 0..4294967295 4
shortint -128..127 1
smallint -32768..32767 2
longint -2147483648..2147483647 4
int64 -263..263-1 8
Byte 0..255 1
word 0..65535 2
longword 0..4294967295 4
Целые типы данных предназначены для представления целых чисел.
Наибольшая производительность процессора и операционной системы достигается
при использовании типов integer и cardinal.
К переменным целого типа можно применять операции целочисленного деления
div и mod. Если a и b – переменные целого типа, то
a div b – это целая часть частного от деления a на b;
a mod b – это остаток от деления a на b.
Например, 9 div 2 = 4 9 mod 2 = 1
При применении к данным целого типа операций
* div mod + –
полученный результат будет также целого типа. То же можно сказать и о
стандартных функциях abs и sqr. Операция деления / над целочисленными
операндами даёт результат вещественного типа. Если в арифметическом выражении
используются значения только какого-нибудь одного из целых типов, то результат
выражения будет иметь такой же тип. Если же в выражении используются значения
разных типов, то результат будет иметь тип integer. Для данных целого типа
определены процедуры:
inc(i, k) – увеличивает значение i на k единиц; если k не задано, то на 1;
dec(i, k) – уменьшает значение i на k единиц; если k не задано, то на 1.
2.2. Разработка программ с разветвлениями
В Delphi данные логического (булева) типа могут принимать одно из двух значений: true (истина) или false (ложь). Логические типы, определённые в Object Pascal: Таблица 2 - Логические типы
Тип Размер (в байтах)
Boolean 1
ByteBool 1
WordBool 2
LongBool 4
Основным логическим типом в Delphi 7 является Boolean. Остальные типы
нужны для совместимости с логическими данными, используемыми в Windows и
некоторых других системах программирования, например Visual C.
В логических выражениях можно использовать логические операции: not
(отрицание), and (логическое И), or (логическое ИЛИ), xor (логическое исключающее
ИЛИ). Результат применения этих операций к операндам логического типа
представлен в следующей таблице.
При записи логических выражений нужно помнить, что первой выполняется
операция not, затем and, потом or и xor. Операции отношения выполняются в
последнюю очередь.
Логические поразрядные операции предназначены для поразрядной обработки
целочисленных операндов, представленных в двоичном виде. Такими операциями
являются поразрядные отрицание (not), и (and), или (or), исключающее или (xor), а
также поразрядные сдвиг влево (shl) и сдвиг вправо (shr). Расмотрим пример. Пусть
переменные a и b типа byte имеют значения 3 и 5 соответственно. В двоичном
представлении эти числа будут иметь вид : 00000011 и 00000101. Вычислим a xor
b. Операция xor будет применяться поразрядно, т.е. к каждой паре чисел, стоящих в
одинаковых позициях. Результат можно определить при помощи приведённой выше
таблицы, если мысленно заменить 0 словом false, а 1 – словом true. Получим
00000110 = 6 (10). Операции shl и shr сдвигают значение переменной влево или
вправо на указанное количество битов (например a shl 1 – сдвиг влево на 1 бит).
При этом начальные или конечные биты теряются, а вновь появившиеся биты
содержат нулевые значения. Это эквивалентно умножению на 2 в степени, равной
количеству разрядов смещения.
Вещественные типы не являются порядковыми. Поскольку данные в компьютере хранятся в виде двоичных кодов, то действительные числа, в отличие от целых, представляются приближённо, хотя и с большой степенью точности.
: Таблица 3 - Вещественные типыТип Диапазон значений Размер (в байтах)
Параметр S – это строка типа string или динамический массив. Функция Copy
возвращает подстроку строки S, начинающуюся с символа с номером Index и
содержащую Count символов.
procedure Delete(var S : string; Index, Count : integer);
Удаляет из S подстроку, начинающуюся с символа с номером Index и содержащую
Count символов.
procedure Insert(Substr : string; S : string; Index : integer);
Вставляет строку Substr в S, начиная с символа с номером Index.
function Length(S : string): integer;
Возвращает число символов в строке S.
function Pos(Substr, S : string): integer;
Возвращает позицию (индекс) первого вхождения подстроки Substr в строку S. Если
Substr нет в S, то возвращается 0.
procedure SetLength(var S; NewLength : integer);
Параметр S является строкой или динамическим массивом. Процедура устанавливает
новую длину NewLength строки S. Если строка имеет тип ShortString, то значение
параметра NewLength должно находиться в диапазоне 0..255. Для длинных строк
значение параметра NewLength ограничено лишь размерами доступной памяти
компьютера. При увеличении длины строки старые значения, находившиеся там,
сохраняются, а во вновь добавленных позициях находятся неопределённые значения.
function StringOfChar(Ch : char; Count : integer): string;
Создаёт строку, состоящую из Count раз повторяющегося символа Ch.
function Trim(const S : string): string;
Удаляет из строки S начальные и завершающие пробелы и управляющие символы.
Строковые выражения.
Над строками определены операции отношения. Строки сравниваются по кодам
символов. Напомним, что для консольных приложений используется кодировка
ASCII, а для оконных – ANSI. При сравнении двух строк последовательно
сравниваются коды символов, стоящих в одинаковых позициях. Символы в строках
просматриваются слева направо. Если в очередной паре оказываются различные
символы, то большей считается та строка, символ которой имеет больший код. На
этом сравнение прекращается. Если сравниваются строки разной длины, причём
одна строка совпадает с началом другой, то большей будет более длинная строка.
Например,
муха < слон
слон < слоник
2 > 123
Кроме операций отношения над строками определена операция сцепления
(конкатенации), которая обозначается знаком + . Например,
Object + Pascal = Object Pascal
Строки разных типов могут смешиваться в одном выражении, переменным
одного строкового типа можно присваивать значения другого строкового типа.
Компилятор при этом осуществляет автоматическое приведение типов. Если
переменной типа ShortString присваивается в качестве значения строка, длина
которой больше 255, то лишние символы отбрасываются.
Для ввода символьных строк необходимо использовать процедуру readln, а не
read. Это объясняется тем, что в конце каждой символьной строки, вводимой с
клавиатуры, стоит так называемый разделитель строк EOLN (end of line) –
последовательность кодов #13(CR – перевод каретки) и #10(LF – переход на начало
строки). Разделитель строк вставляется во вводимый текст при нажатии на клавишу
Enter. Процедура readln считывает все символы, расположенные до разделителя
строк, а затем и символы разделителя строк (#13 и #10), которые являются
управляющими и переводят курсор дисплея в начало следующей строки.
Пример . Используя стандартные функции для строк, получить из строки
'grammofon' строку fonogramma.
var t, s : string; i, j : integer; Комментарий
begin
s:='grammofon';
i:=pos('o', s); i = 6
t:=copy(s, 1, i-1); t = gramm
delete(s, 1, i); s = fon
j:=length(s); j = 3
s:= s + t + 'a'; s = fongramma
insert('o', s, j+1); s = fonogramma
writeln(s); readln
end.
Преобразование строк в числовые типы и обратно.
Задача преобразования строк в числовые типы и обратно для консольных
приложений не актуальна, так как процедуры read, readln, write, writeln выполняют
эти преобразования автоматически. Основная область применения этих подпрограмм
– оконные приложения, при создании которых программист сам должен
предусматривать преобразование типов.
procedure Str(x; var s:string);
Преобразует целое или действительное значение x в строку s (параметр x может
иметь указание формата вывода).
procedure Val(s:string; var v; var code:integer);
Преобразует строку s в целую или вещественную переменную v. Параметр code
равен нулю, если преобразование прошло успешно, в противном случае он равен
номер позиции в строке s, где обнаружен ошибочный символ. Например: если
s:='95'; , то в результате выполнения val(s,x,d); x = 95, d=0. Если s=a4, то x=0, d=1.
function StrToInt(s:string):integer;
Возвращает целое число, изображением которого является строка s.
function StrToFloat(s:string):extended;
Возвращает вещественное число, изображением которого является строка s.
function IntToStr(n:integer):string;
Возвращает строку, являющуюся изображением целого числа n.
function FloatToStr(n:extended):string;
Возвращает строку, являющуюся изображением вещественного числа n.
function FloatToStrF(n:extended; format; k, m:integer):string; – строка, являющаяся
изображением вещественного n в различных форматах;
при вызове функции указываются:
format – формат (способ изображения);
k – общее количество цифр;
m – количество цифр после десятичной точки.
Значениями параметра format могут быть следующие константы:
ffFixed – число представляется в формате с фиксированной десятичной точкой.
ffExponent – научный формат (экспоненциальная форма записи).
ffGeneral – общий цифровой формат.
ffNumber – аналогичен ffFixed, но в изображении числа используется разделитель
групп разрядов.
ffCurrency – денежный формат.
Например: если x=3.587 и s:=floattostrf(x, ffFixed, 7, 3); , то s = 3,587 (используется
десятичная запятая).
2.7. Структурированные типы данных.
Запись – это структура данных, состоящая из фиксированного числа
компонентов, называемых полями записи. Компоненты (поля) записи могут быть
различного типа.
Описание типа запись:
имя типа record список полей end;
Здесь имя типа – правильный идентификатор. Список полей представляет собой
последовательность разделов записи, между которыми ставится точка с запятой.
Каждый раздел записи состоит из одного или нескольких идентификаторов полей,
отделённых друг от друга запятыми. За идентификатором ставится двоеточие и
описание типа поля.
Пример. Запись в телефонной книге может быть представлена в виде следующей
структуры данных:
type tel = record
number : integer;
fio : string[40];
adr : string[60]
end;
var m, v : tel;
Обращение к значению поля осуществляется с помощью идентификатора переменной
записи и идентификатора поля, разделённых точкой. Например:
m.number; m.fio; m.adr;
Поля записи используются в программе как обычные переменные соответствующего
типа. Например, можно написать
m.numberm.number 1; или m.fio[1]<>Ф
Допускается применение оператора присваивания к записи в целом. Например,
vm; После выполнения этого оператора значения полей записи v станут равны
значениям соответствующих полей записи m. Логические операции сравнения для
записей не определены. Тип запись нельзя использовать для описания типа
функции.
Обращение к полям записи имеет несколько громоздкий вид. Для решения этой
проблемы в языке Паскаль предназначен оператор присоединения with , который
имеет следующий формат:
with переменная типа запись do оператор;
Один раз указав переменную типа запись в операторе with , можно далее работать
с именами полей без указания перед идентификатором поля имени записи.
Например:
with m do begin number1364; fioПетров end;
Пример 50. Описать тип point для точки на плоскости со следующими полями:
буква, обозначающая точку, координата x, координата y. Даны две точки. Найти
длину отрезка, соединяющего эти две точки.
type point = record
name : 'A' .. 'Z';
x : real;
y : real
end;
var a, b : point; ab : real;
begin
readln(a.name, a.x, a.y);
with b do
readln(name, x, y);
ab:=sqrt(sqr(b.x – a.x) + sqr(b.y – a.y));
writeln(a.name, b.name, ' = ', ab:5:2); readln
end.
Множественный тип представляет собой конечный набор значений некоторого
базового типа. В качестве базового типа может использоваться любой порядковый
тип, кроме word, integer, longint, int64.
Описание множественного типа имеет вид:
<имя типа > = set of <базовый тип>;
Например:
type mn1 = set of A . . Z;
mn2 = set of 1 . . 5;
Значениями переменных множественного типа являются любые подмножества
базового множества. Для задания множества используется конструктор множества,
представляющий собой список элементов базового множества, разделённых запятыми
и обрамлённый квадратными скобками.
Пример.
type digitChar set of 0 .. 9;
digit set of 0 .. 9;
var s1, s2 : digitChar; s3, s4, s5 : digit;
begin
s1[1, 2, 3]; s2[3, 2, 1];
s3[0..3, 6]; s4[4, 5]; s5[3..9]
end.
[] – пустое множество. Над множествами определены операции:
– пересечение множеств.
s3s4=[]; s3s5=[3, 6];
– объединение множеств.
s3+s4=[0 .. 6];
– – разность множеств.
s5 – s4=[3, 6 .. 9];
= – проверка эквивалентности множеств, возвращает true, если множества
эквивалентны.
s1=s2
<> – проверка неэквивалентности.
<= – проверка вложения.
s4<=s5 результат true.
in – проверка принадлежности.
7 in s5 результат true.
Стандартные процедуры для работы с множествами:
include(s, i) – включает элемент i базового типа в множество s.
exclude(s, i) – исключает элемент i из множества s.
Использование множеств позволяет сделать программы более эффективными за
счёт уменьшения количества различных проверок.
Пример . Используя метод Решето Эратосфена напечатать все простые числа из
диапазона 1..30.
Суть метода – вычёркиваем из исходного множества [1..30] те числа, которые
не являются простыми.
var n : set of 1..30; k, s : integer;
begin
n:=[1..30];
for s:=2 to 15 do
if s in n then
for k:=s+1 to 30 do
if k mod s=0 then exclude(n, k);
for s:=1 to 30 do
if s in n then write(s:3);
readln
end.
Программа работает следующим образом. Вначале s=2. Это значение
принадлежит n, поэтому, начиная с числа 3, вычёркиваем все числа, кратные 2.
Теперь s=3. Это значение принадлежит n, поэтому, начиная с числа 4,
вычёркиваем все числа, кратные 3. Теперь s=4. Это значение уже вычеркнуто из n.
Переходим к s=5 и так далее. Вывод на экран элементов полученного множества
осуществляем следующим образом: перебираем все элементы базового множества и
отбираем для печати те из них, которые принадлежат n.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
2.8. Файлы
Object Pascal располагает средствами создания и обработки файлов различных
типов. Доступ к файлу осуществляется с помощью переменных файлового типа. В
Object Pascal существует три файловых типа:
TextFile – текстовый файл, представляющий собой набор символьных
строк переменной длины;
File of < тип > – типизированный файл, представляющий собой набор
данных указанного типа;
File – нетипизированный файл, представляющий собой набор
неструктурированных данных.
Примеры описания файловых переменных:
var f1: textfile; f2: file of integer; f3: file of char; f4: file;
Здесь f1 – текстовый файл, f2 и f3 – типизированные файлы, f4 – нетипизированный
файл.
Стандартные подпрограммы для доступа к файлам.
Работа с файлами заключается в записи и считывании информации. Для того
чтобы указать, с каким элементом будет производиться очередная операция чтения
или записи, существует понятие указателя на доступный элемент файла. После
каждого чтения или записи указатель перемещается на следующий элемент файла.
Перед использованием файловой переменной она должна быть связана с
внешним файлом ( файлом на диске) с помощью вызова процедуры
AssignFile(< файловая переменная>, < имя файла>);
здесь <файловая переменная> – имя переменной файлового типа, объявленной в
программе; <имя файла> – символьная строка, содержащая имя файла. Если файл
находится в одной папке с обрабатывающей его программой, то достаточно указать
только имя файла, в противном случае надо указать полный путь к файлу,
например:
c:\files\z1.txt
Когда связь с внешним файлом установлена, его можно открыть для ввода или
вывода информации. Существующий файл можно открыть с помощью процедуры
Reset(<файловая переменная>);
Процедура reset открывает существующий внешний файл, имя которого было
связано с файловой переменной. Если внешний файл с указанным именем
отсутствует, то возникает ошибка периода выполнения программы. Если файл уже
открыт, то он сначала закрывается, а затем открывается вновь. Файловый указатель
устанавливается на элемент файла с порядковым номером 0.
Текстовый файл, открытый процедурой reset, доступен только для чтения. Для
типизированных и нетипизированных файлов, открытых процедурой reset,
допускается выполнять операции чтения и записи в файл.
Новый файл можно создать и открыть для записи с помощью процедуры
Rewrite(<файловая переменная>);
Процедура rewrite создаёт новый файл, имя которого связано с файловой
переменной. Если файл с указанным именем уже существует, то он удаляется и на
его месте создаётся новый пустой файл. Текущая позиция в файле устанавливается
на начало файла, т.е. указатель будет указывать на элемент с порядковым номером
0.
Если процедура rewrite открывает текстовый файл, то он становится доступным
только для записи. Для типизированных и нетипизированных файлов, открытых
процедурой rewrite, допускается выполнять операции чтения и записи в файл.
Текстовый файл может быть открыт процедурой
Append(<файловая переменная>);
Процедура append открывает уже существующий внешний файл, связанный с
файловой переменной, для добавления новой информации. Если файла с указанным
именем не существует, то возникает ошибка. Если файл уже открыт, то он сначала
закрывается, а затем открывается заново. Указатель будет указывать на конец
файла. В результате обращения к append текстовый файл становится доступным
только для записи.
Когда программа завершает обработку файла, он должен быть закрыт с
помощью стандартной процедуры
CloseFile(<файловая переменная>);
Процедура closefile закрывает открытый файл. При этом обеспечивается
сохранение в файле всех новых записей и регистрация файла в папке. Процедура
closefile не разрывает связь файла с файловой переменной, поэтому файл можно
открыть снова без повторного использования процедуры assignfile.
Текстовые файлы.
Текстовый файл представляет собой последовательность символов,
сгруппированных в строки произвольной длины, где каждая строка заканчивается
маркером конца строки – EOLN (end of line), состоящим из двух символов: CR=#13 и
LF=#10. Заканчивается файл символом конца файла EOF (end of file, код #26).
Чтение данных из произвольного текстового файла можно осуществить с
помощью процедур read и readln. При этом в списке их параметров первой должна
стоять соответствующая файловая переменная. Например, процедура read(f, x, y, z);
осуществляет чтение из файла, связанного с файловой переменной f, значения
переменных x, y, z. Процедура readln(f, a);
прочитает из файла, связанного с переменной f, значение переменной a и перейдёт
в этом файле к следующей строке.
Вывод данных в текстовый файл производится процедурами write и writeln, у
которых первой в списке параметров указана соответствующая файловая переменная.
Например, процедура write(f, s = , s) осуществляет запись в файл, связанный с
переменной f, символьной строки s = и значения переменной s. Процедура
writeln(f) запишет в файл, связанный с переменной f, пустую строку.
При работе с текстовыми файлами используются логические функции
eof(<файловая переменная>) и eoln(<файловая переменная >). Функция eof
возвращает значение true, если достигнут конец файла, и false в противном случае.
Функция eoln возвращает значение true, если достигнут конец строки в текстовом
файле, и false в противном случае.
Текстовый файл можно создать в среде Delphi, выбрав в меню команду
File�New�Text. В открывшемся окне нужно набрать содержимое текстового файла и
сохранить файл с помощью команды File�Save. Текстовый файл можно также
создать программным способом. Рассмотрим несколько возможных вариантов
программы для создания текстового файла.
Типизированные файлы.
Типизированный файл содержит элементы одного типа. Тип элементов может
быть любым, кроме файлового. Создать и просмотреть такой файл при помощи
текстового редактора как текстовый файл нельзя. Поэтому обработка таких файлов
должна осуществляться программным путём. Напомним, что описание файловой
переменной, соответствующей типизированному файлу имеет вид:
var <имя файловой переменной> : file of <тип>;
Для чтения данных из типизированного файла применяется процедура read.
Список ввода процедуры read должен содержать переменные того же типа, что и
элементы файла. Для записи в типизированный файл используется процедура write,
список вывода которой должен содержать переменные того же типа, что и
элементы файла. Процедуры readln и writeln для типизированных файлов не
применяются.
Доступ к текстовым файлам возможен только последовательно, то есть, когда
элемент считывается или записывается, указатель файла перемещается к
следующему по порядку элементу файла. К типизированным файлам можно
организовать прямой доступ с помощью стандартной процедуры
procedure seek( var f; n:longint);
которая перемещает файловый указатель в типизированном файле, связанном с
файловой переменной f, на элемент с номером n. Нумерация элементов в файле
начинается с нуля. Для определения текущей позиции в файле используется
функция
function filepos( var f):longint;
Для определения размера файла используется функция
function filesize( var f):integer;
Например, для установки файлового указателя на последний элемент файла f
достаточно записать
seek(f, filesize(f)–1);
на первый элемент файла
seek(f, 0);
вернуться на один элемент назад
seek(f, filepos(f)–1);
Применение процедур assignfile и closefile для типизированных файлов не
отличается от текстовых файлов. Процедура reset, в отличие от текстовых файлов,
допускает для типизированных файлов не только чтение, но и запись в файл.
Процедура rewrite, в отличие от текстовых файлов, допускает не только запись, но
и чтение из файла. Процедура append и функция eoln для типизированных файлов
не работают.
Нетипизированные файлы.
С точки зрения Object Pascal, нетипизированный файл представляет собой
последовательность байтов, содержащих данные произвольного типа и структуры.
Основное назначение нетипизированных файлов – обеспечение совместимости с
любыми типами файлов и организация высокоскоростного обмена данными между
внешними запоминающими устройствами и оперативной памятью. Описание
нетипизированного файла f имеет вид:
var f : file;
В процедурах reset и rewrite для нетипизированных файлов указывается
дополнительный параметр RecSize, чтобы задать размер записи, используемой при
передаче файла:
procedure reset (var f : file {; RecSize : word});
procedure rewrite (var f : file {; RecSize : word});
Если параметр RecSize не указан, то принимаемая по умолчанию длина
записи равна 128 байтам. Длина записи измеряется в байтах и может быть задана
произвольным целым числом – от 1 байта до 2 Гбайт. Если задать длину записи,
кратную 512 байт, то это позволит выполнять операции чтения-записи для
нетипизированного файла с максимальной скоростью.
За исключением процедур read и write для нетипизированных файлов
можно использовать все стандартные процедуры, которые допускается использовать
для типизированных файлов. Вместо процедур read и write используются
процедуры blockread и blockwrite, позволяющие пересылать данные с высокой
скоростью:
procedure blockread( var f : file; var buf; count : integer; {var at : integer});
procedure blockwrite( var f : file; var buf; count : integer; {var at : integer});
Здесь f – имя файловой переменной, связанной с нетипизированным файлом,
buf – переменная, в которую будут помещаться данные при чтении из файла или из
которой будут извлекаться данные при записи в файл. Count – параметр целого
типа, указывающий, какое количество записей необходимо прочитать или записать
за одно обращение к файлу. Переменная buf должна иметь длину равную
count�RecSize байт. Необязательный параметр at содержит количество реально
прочитанных или записанных записей.
2.9. Классы и объекты
Объектно-ориентированное программирование (ООП) – это методика разработки
программ, в основе которой лежит понятие объекта, как некоторой структуры,
описывающей объект реального мира, его поведение. Задача, решаемая с
использованием методики ООП, описывается в терминах объектов и операций над
ними, а программа при таком подходе представляет собой набор объектов и связей
между ними.
Строго говоря, для разработки оконного приложения в Delphi на базе
компонентов, предоставляемых средой разработки, знание концепции ООП не
является необходимым. Однако материал данной главы будет весьма полезен для
более глубокого понимания того, как программа взаимодействует с компонентами,
что и почему Delphi добавляет в текст программы.
Язык Object Pascal, поддерживая концепцию объектно-ориентированного
программирования, даёт возможность определять классы. Описание типа class
напоминает описание типа record (запись), но тип class кроме описания полей
данных содержит ещё методы (процедуры и функции).
Объект в Object Pascal – это конкретный экземпляр класса. Переменная-объект
понимается как динамическая структура, то есть содержит не данные, а ссылку на
данные объекта. Выделение памяти под эти данные осуществляется при помощи
специального метода – конструктора (constructor).
Пример объявления простого класса:
type tPerson = class
fname : string[15];
faddress : string[45];
fage : byte;
procedure show;
end;
var boy1 : tPerson;
В основе объектно-ориентированного программирования лежат три основных
принципа: инкапсуляция, наследование и полиморфизм.
Инкапсуляцией называется объединение в классе данных и подпрограмм для их
обработки. Данные содержатся в полях класса, а процедуры и функции называются
методами. В соответствии с правилами объектно-ориентированного
программирования прямой доступ к полям нежелателен. В связи с этим в Object
Pascal предусмотрены специальные конструкции, называемые свойствами, которые
осуществляют чтение или запись в поля при помощи вызова соответствующих
методов. Общепринятым является правило давать названия классам, начинающиеся с
буквы t. Например:
type tPerson = class;
Наследование означает, что класс может наследовать компоненты другого класса. Создать новый класс от некоторого класса-родителя можно следующим образом:
type tStudent = class(tPerson);
Принцип наследования заключается в том, что порождённый класс-потомок
автоматически наследует поля, методы и свойства своего родителя, и в тоже время
может дополнять их новыми.
В Object Pascal все классы являются потомками класса tObject. Этот класс не
включает в себя полей и свойств, зато его методы позволяют создавать,
поддерживать работу и удалять объекты. Если программист хочет создать класс,
являющийся непосредственным потомком класса tObject, то имя класса-родителя в
этом случае можно не указывать, т.е. следующие строки являются эквивалентными:
type tNewClass = class(tObject);
type tNewClass = class;
Использование принципа наследования в Delphi привело к созданию
разветвлённого дерева классов. В верхней части этого дерева находятся так
называемые абстрактные классы, для которых нельзя создать полноценные
работающие объекты. Но вместе с тем абстрактные классы являются
родоначальниками больших групп классов, для которых уже создаются реальные
объекты.
Полиморфизм позволяет использовать одинаковые имена для методов,
входящих в различные классы. Принцип полиморфизма обеспечивает в случае
обращения к одноимённым методам выполнение того из них, который соответствует
классу объекта.
В общем виде класс объявляется в разделе type следующим образом:
type < имя класса > = class(< имя класса-родителя >)
public
< описание общедоступных элементов >
published
< описание элементов, доступных в Инспекторе Объектов >
protected
< описание элементов, доступных в классах-потомках >
private
< описание элементов, доступных только в модуле >
end;
Секции public, published, protected, private могут содержать описания полей, методов,
свойств, событий.
Следующий пример иллюстрирует создание объекта типа tPerson, обращение к
его полям и методам.
type tPerson = class
private
fname : string[15];
faddress : string[45];
fage : byte;
public
procedure show;
end;
var boy1 : tPerson;
procedure tPerson.show;
begin
writeln('Surname?'); writeln(fname);
writeln('Address?'); writeln(faddress);
writeln('Age?'); writeln(fage);
end;
begin
boy1:=tPerson.Create; boy1.fname:='Ivanov';
boy1.faddress:='Kolzovskaja, 59-45';
boy1.fage:=16; boy1.show;
readln;
end.
После описания типа класса tPerson следует описание реализации методов. В
заголовке имя метода дополняется именем класса, к которому данный метод
относится (procedure tPerson.show;). В теле метода обращение к полям класса
происходит без указания имени класса. Создание объекта boy1 происходит в
результате применения конструктора Create к имени класса. Для того чтобы
обратиться к полю объекта, нужно написать имя объекта и имя поля, разделённые
точкой (boy1.fage). Аналогично записывается вызов метода объекта (boy1.show).
Классы, созданные разработчиками Delphi, образуют сложную иерархическую