Некоммерческое акционерное общество

АЛМАТИНСКИЙ УНИВЕРСИТЕТ ЭНЕРГЕТИКИ  И СВЯЗИ

Кафедра компьютерных технологий

 

 

ПРОГРАММИРОВАНИЕ В DELPHI 

Методические указания к выполнению лабораторных работ

для студентов всех форм обучения специальности

5B070400 – Вычислительная техника и программное обеспечение

 

 

Алматы 2011 

СОСТАВИТЕЛИ: С.Б. Бимурзаев, З.А. Жунусов. Программирование в Delphi. Методические указания к выполнению лабораторных работ по курсу “Программирование на алгоритмических языках” для студентов всех форм обучения специальности 5B070400 – Вычислительная техника и программное обеспечение. – Алматы, АУЭС, 2011. – 68 с.

 

Методические указания посвящены изучению основ программирования на языке Pascal в среде Delphi. В них рассмотрены такие разделы языка Pascal, как управляющие структуры, принципы модульного программирования, а также алгоритмы обработки массивов и строк, важные для любого языка программирования. При этом для создания проектов (программ) использована технология визуального программирования.

Методические указания предназначены для студентов всех форм обучения по специальности 5B070400 – Вычислительная техника и программное обеспечение. Они могут быть использованы и для организации лабораторных занятий по идентичным темам аналогичных дисциплин, запланированных для других специальностей.

Ил. - 31, рисунков - 29, таблиц – 2, библиогр. – 7 назв. 

 

Рецензент: канд. физ.-мат. наук, доцент Т.Т. Коржымбаев

 

Печатается по плану издания Некоммерческого акционерного общества “Алматинский институт энергетики и связи” на 2010 г.

 

© НАО “Алматинский университет энергетики и связи”, 2011 г.

 

 

 

 

 

Свод. план 2010 г., поз. 195

 

 

 

 

 

 

 

Введение

 

Целью этих методических указаний является практическое изучение основ программирования на языке Pascal в среде Delphi.

Pascal – это язык структурного программирования, с которого обычно начинается обучение программированию. В нем присутствуют такие элементы любого структурного языка программирования, как управляющие структуры (последовательная структура, структуры выбора и повторения) и подпрограммы (функции и процедуры), без которых невозможно представить себе программирование.

В качестве среды разработки выбрана среда Delphi – продукт фирмы Borland, разработавшей в свое время Turbo Pascal. Выбор в пользу Delphi вместо Turbo Pascal обусловлен рядом причин. Во-первых, программирование в Delphi интереснее для обучающихся. А интерес – непременное условие успешного обучения. Во-вторых, можно существенно сократить изучение элементов языка Turbo Pascal, связанных с вводом информации с экрана и выводом ее на экран. В-третьих, Delphi – это среда визуального программирования.

Визиуальное программирование кардинально упростило процесс проектирования приложений (программ), сведя его к простым и наглядным процедурам, которые в Delphi выглядят примерно так.

Интегрированная Среда Разработки Delphi предоставляет окно формы. На форму переносятся и размещаются компоненты с помощью мыши. Размеры и расположения этих компонентов можно изменять путем простых манипуляций. При этом результат процесса проектирования – изображения формы и компонентов виден все время, даже без компиляции. Но самое главное достоинство визуального программирования состоит в том, что во время проектирования формы и размещения на ней компонентов Delphi автоматически формируют коды программ, описывающие тот и другой компонент, включая форму. Затем в соответствующих диалоговых окнах можно изменить значения каких-то свойств, заданных по умолчанию, этих компонентов. И, наконец, при необходимости написать обработчики каких-то событий, наступающих при нажатии кнопок мыши на соответствующем компоненте.

Так как целью учебного курса является изучение основ программирования на языке Pascal, а не изучение Delphi, то схема организации курса выглядит так:

1.     Познакомить:

- как создать новый проект и сохранить его;

- как перенести на форму компоненты;

- как написать обработчики событий;

2.     Далее изучать курс программирования, который обычно изучается с ориентацией на Turbo Pascal

 

Лабораторная работа 1. Знакомство с Интегрированной средой разработки Delphi

 

Цели работы:

- познакомиться с Интегрированной средой разработки Delphi;

- научиться создавать и сохранять проекты;

- научиться размещать на форме компоненты;

- научиться задавать свойства компонентов;

- научиться задавать обработчики событий.

 

1.1 Знакомство с ИСР

        

Интегрированная Среда Разработки (ИСР) — это среда, в которой есть все необходимое для проектирования, запуска и тестирования приложений и где все нацелено на облегчение процесса создания программ. ИСР интегрирует в себе редактор кодов, отладчик, инструментальные панели, редактор изображений, инструментарий баз данных — все, с чем приходится работать. Эта интеграция предоставляет разработчику гармоничный набор инструментов, дополняющих друг друга.

При запуске Delphi, перед вами откроется основное окно Интегрированной Среды Разработки. Его вид представлен на рисунке 1.1.

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

Правее полосы главного меню размещена еще одна небольшая инструментальная панель, содержащая выпадающий список и две быстрые кнопки. Это панель сохранения и выбора различных конфигураций окна ИСР, которые вы сами можете создавать и запоминать.

В основном поле окна вы можете видеть слева два окна: сверху — Дерево Объектов (Object TreeView), под ним — Инспектор Объектов (Object Inspector). Окно Дерево Объектов будет отображать иерархическую связь компонентов и объектов вашего приложения. А Инспектор Объектов — это основной инструмент, с помощью которого вы в дальнейшем будете задавать свойства компонентов и обработчики событий. Правее этих окон вы можете видеть окно пустой формы, готовой для переноса на нее компонентов. Под ним расположено окно Редактора Кодов. Обычно оно при первом взгляде на экран невидимо, так как его размер равен размеру формы и окно Редактора Кодов практически полностью перекрывается окном формы. На рисунке 1.1 это окно немного сдвинуто и выглядывает из-под окна формы.

 

 

Рисунок 1.1 - Основное окно Интегрированной Среды Разработки Delphi

 

1.2 Создание и сохранение нового проекта

 

Чтобы создать новый проект, нужно выполнить команду File|New, и в открывшемся каскадном меню выбрать раздел Application. В результате будет создан новый проект и откроется пустая форма.

Первое действие, которое необходимо выполнить после создания нового проекта — сохранить его. Сохранить проект можно командой File|Save All. Удобно также использовать соответствующую быструю кнопку.

При первом сохранении Delphi спросит у вас имя файла сохраняемого модуля, а затем — имя файла проекта. Дело в том, что каждый проект состоит из нескольких файлов: файл проекта с расширением .dpr, файл модуля формы с расширением .pas, и несколько других файлов. Имена этих дополнительных файлов совпадают с именем проекта или модуля. Так что при сохранении надо дать имена только файлу проекта и модуля. При этом задаваемые вами имена файлов должны быть разными, так как Delphi не допускает одинаковых имен модулей и проектов

При разработке простых проектов удобно задавать имена файлов проектов и модулей одинаковыми, различая их только префиксом «Р» или «U» соответственно. Например, файл проекта — PEditor1, файл модуля — UEditor1. Это упрощает понимание того, какие файлы к какому варианту проекта относятся, поскольку на начальных стадиях проектирования у вас может появиться несколько альтернативных вариантов одного и того же проекта.

Так что в нашем примере можете дать сохраняемым файлам имена, например, PSimple и USimple.

Заведите для каждого нового проекта новый подкаталог (папку Windows). Удобная структура каталогов существенно облегчает работу над проектами.

Итак, рекомендации по созданию нового проекта сводятся к следующему.

- Создайте новый каталог для своего нового проекта.

- Создайте новый проект командой File|New|Application.

- Сразу сохраните проект и файл модуля командой File | Save All.

 

1.3 Открытие проекта

 

Для того чтобы открыть сохраненный проект применяется команда File|Open Project. Но если вы работали с проектом недавно, то много удобнее открыть его командой File|Reopen. А еще удобнее воспользоваться стрелочкой рядом с соответствующей этой команде быстрой кнопкой. В обоих случаях открывается окно, показанное на рисунке 1.2. В его верхней части вы найдете несколько проектов, с которыми работали в последнее время, а в нижней части — ряд файлов, с которыми вы работали.

        

0       F:\HELP\ForInter\D71\NewD8.dpr

1       F:\HElP\ForInter\D71\SetupH7.dpr

2       F:\HELP\Forlnter\D71\PGTestDLL71.bpg

3       F:\HELP\ForInter\071\Set_cdb_cbd.dpr

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

 

5       F:\HELC\Forlnter\D71\UHelp.pas

6       F:\HELP\ForInter\D71\USet_cdb_cbd.pas

7       F:\HELP\ForInter\D71\USetup63.pas

8       F:\HELP\ForInter\D63\UHelp.pas

9       F:\HELP\ForInter\861\UHelp.dfm

A       F:\HELP\ForInter\B52\UHelp.dfm

В       F:\HELP\ForInter\B51\UhelpDB.dfm

С       r:\HElP\ForInter\B51\UhelpDB.pas

D       с:\HElP\ForInter\D61\Uhelp.Dfm

Е       F:\HElP\ForInter\D61\Uhelp.pas

 

Рисунок 1.2 - Окно предшествующих проектов и файлов

 

Предупреждение

Проект можно выбирать только в верхней части окна рисунка 1.2. Если вы выберете имя из нижней части окна (очень частая ошибка у начинающих!), то просто откроете файл модуля, который никак не будет связан с вашим проектом. В этом случае все, что вы делаете с открывшейся формой, не будет видно, когда вы выполняете ваш проект.

 

Совет

Начинающие работать с Delphi часто закрывают окна, которые им в данный момент мешаются: форму, Редактор Кода, Инспектор Объектов. Не надо этого делать. Но если все-таки по ошибке вы закрыли то или иное окно, его можно сделать видимым командами View|Object Inspector (окно Инспектора Объектов), View|Units (окно Редактора Кода), View|Forms (окно формы).

 

1.4 Компоновка формы и размещение на ней компонентов

 

Итак, вы создали новый проект и сохранили его. Теперь давайте спроектируем в нем приложение. Пусть окно этого приложения должно иметь кнопку, при щелчке на которой будет появляться некоторая надпись. Так что вам следует поместить на форму проекта требуемые компоненты. Для этого, конечно, надо, чтобы форма было видна. Но она может оказаться у вас загороженной окном Редактора Кода. В этом случае щелкните на быстрой кнопке Toggle Form|Unit — она третья слева на нижней панели быстрых кнопок или клавишу F12. Каждый щелчок на этой кнопке переключает фокус между формой и окном Редактора Кодов с загруженным в нем текстом модуля, соответствующего форме.

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

Поскольку число предопределенных компонентов, конечно, возрастает от версии к версии, то наиболее полной является библиотека Delphi 7. Палитра этой библиотеки приведена на рисунке 1.3.

 

 

Рисунок 1.3 - Палитра компонентов в Delphi 7

 

Чтобы перенести компонент на форму, надо открыть соответствующую страницу библиотеки и указать курсором мыши необходимый компонент. Поместить выбранный компонент на форму очень просто — надо сделать щелчок мышью в нужном месте формы.

Если вы выбрали компонент, а затем изменили ваше намерение размещать его, вам достаточно нажать кнопку указателя слева на палитре. Это прервет процесс размещения компонента, и программа вернется в нормальный режим, в котором вы можете выбирать другой компонент или выполнять какую-то команду.

Чтобы удалить ошибочно перенесенный на форму компонент, выделите его и нажмите клавишу Delete.

В нашем примере вам надо перенести на форму кнопку и метку (надпись) — это компонент, отображающий заданный в нем текст. Для кнопки выберите компонент Button со страницы Standard. Выделите пиктограмму кнопки (она седьмая слева на рисунке 1.3 с надписью «ОК») и затем щелкните курсором мыши в нужном вам месте формы. На форме появится кнопка, которой Delphi присвоит имя по умолчанию — Button1. Аналогичным образом перенесите на форму с той же страницы Standard палитры компонентов метку Label (она на странице четвертая слева с надписью «А»). В этой метке в процессе выполнения приложения будет появляться текст при нажатии пользователем кнопки. Delphi присвоит ей имя Label1.

Разместите компоненты на форме примерно так, как показано на рисунке 1.4, а.

 

1.5 Задание свойств компонентов

 

Для задания свойств компонентов используется Инспектор Объектов. В нем отображаются свойства того объекта, который выделен на форме. Например, щелкните один раз (одинарный, не двойной щелчок!) на форме. Тогда в окне Инспектора Объектов отобразятся свойства формы. Точнее, это окно имеет две страницы: Properties (свойства) и Events (события). В верхней части окна имеется выпадающий список всех компонентов, размещенных на форме, включая саму форму. В нем вы можете выбрать тот компонент, свойства и события которого вас интересуют. Так что можно этот компонент и не выделять предварительно щелчком мыши на форме

                                     а)                                            б)

       

 

Рисунок 1.4 - Форма (а) и окно в процессе выполнения (б) вашего приложения

 

Вначале обсудим страницу свойств для формы. Вы можете выделить в окне какое-то свойство и изменить его значение в окошке справа от этого свойства. Например, выделите свойство Caption. Это свойство — та надпись, которая видна в окне заголовка вашей формы. По умолчанию значение этого свойства совпадает с именем компонента, к которому свойство относится. В данном случае это «Form1». Измените значение свойства на что-нибудь осмысленное, например: «Приложение Delphi». Вы увидите, что в заголовке формы немедленно появится это значение.

Если щелкнуть на некоторых свойствах, например, на свойстве Color (цвет), то справа от имени свойства откроется окно выпадающего списка. Нажав в нем на кнопочку со стрелкой вниз, вы можете увидеть список возможных значений свойства. Например, смените значение свойства Color с принятого по умолчанию clBtnFace (цвет поверхности кнопок) на clWindow (цвет окна). Вы увидите, что поверхность формы изменит свой цвет.

В выпадающем списке свойства Color в окне Инспектора Объектов вы можете увидеть большой набор предопределенных констант, обозначающих цвета. Все их можно разбить на две группы: статические цвета типа clBlack — черный, clGreen — зеленый и т.д., и системные цвета типа clWindow — текущий цвет фона окон, clMenuText — текущий цвет текста меню и т.д. Если вы задаете статические цвета, они будут оставаться неизменными при работе приложения на любом компьютере. Это не очень хорошо, поскольку пользователь не сможет адаптировать вид вашего приложения к своим потребностям. Так что в большинстве случаев следует использовать для своего приложения палитру системных цветов. Это те цвета, которые устанавливает пользователь при настройке Windows. Когда вы создаете новую форму или размещаете на ней компоненты, Delphi автоматически присваивает им цвета в соответствии со схемой цветов, установленной в Windows. Конечно, вы можете менять эти установки по умолчанию. Но если при этом вы используете соответствующие константы системных цветов, то, когда пользователь изменит цветовую схему оформления экрана Windows, ваше приложение также будет соответственно изменяться, и не будет выпадать из общего стиля других приложений.

Рядом с некоторыми свойствами вы можете видеть знак плюс. Это означает, что данное свойство является объектом, который в свою очередь имеет ряд свойств. Найдите, например, свойство Font (шрифт). Рядом с ним вы увидите знак плюс. Щелкните на этом плюсе или сделайте двойной щелчок на свойстве Font. Вы увидите, что откроется таблица таких свойств, как Color (цвет), Height (высота), Name (имя шрифта) и др. Среди них вы увидите свойство Style (стиль), около которого тоже имеется знак плюс. Щелчок на этом плюсе или двойной щелчок на этом свойстве раскроет дополнительный список подсвойств, в котором вы можете, например, установить в true свойство fsBold (полужирный). Значения true или false (истина или ложь) в подобных свойствах означает соответственно, что свойства включены или выключены. Кстати, для смены true на false и обратно в подобных свойствах не обязательно выбирать значение из выпадающего списка. Достаточно сделать двойной щелчок на значении свойства, и оно изменится. После того как вы просмотрели или изменили подсвойства, вы можете опять сделать двойной щелчок на головном свойстве или щелчок на знаке минус около него, и список подсвойств свернется.

Итак, установите в свойстве Font полужирный стиль шрифта. Теперь посмотрите на вашу форму. Вы увидите, что надписи в метке и на кнопке стали полужирными. Почему так? Ведь вы изменили свойство формы, а не кнопки и метки.

У всех компонентов имеется свойство Parent — родительский компонент. Что такое родительский компонент? Вы поместили компоненты метки и кнопки непосредственно на форме. Как вы увидите далее, часто компоненты размещаются не непосредственно на формах, а на панелях, зрительно объединяющих группы компонентов по их назначению. В этом случае сначала на форме размещаются панели, а потом на них располагаются компоненты. Оконный компонент — форма, панель и т.д., включающий в себя как контейнер другие компоненты, выступает по отношению к ним как родительский компонент. У каждого компонента есть родитель. Им может быть форма или другой оконный компонент.

Что дает понятие родительского компонента? Компонент может наследовать многие свойства своего родителя. Для всех визуальных компонентов вы можете увидеть в Инспекторе Объектов такие свойства, как ParentColor, ParentFont и ParentShowHint, для оконных компонентов имеется еще свойство ParentCtl3D. Эти свойства указывают (если их значения установлены в true), что дочерний компонент наследует от родительского соответственно цвет, атрибуты шрифта, показа ярлычков, атрибуты своего оформления. Именно поэтому при изменении шрифта формы изменились шрифты надписей кнопки и метки. Если бы для компонентов вы задали значение ParentFont = false, этого не произошло бы. Поэкспериментируйте со свойствами Font и ParentFont формы и компонентов, чтобы до конца понять влияние свойства родительского компонента на свойства дочерних компонентов.

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

Имеется еще два важных свойства, которые связывают дочерние компоненты с родительским. Это свойства Visible — видимый, и Enabled — доступный. Если в процессе выполнения приложения сделать в родительском компоненте Visible равным false, то станет невидимым не только родительский, но и все его дочерние компоненты. Аналогично, если в процессе выполнения приложения сделать в родительском компоненте Enabled равным false, то станут недоступными все его дочерние компоненты. Т.е. пользователь не сможет нажимать кнопки и производить любые другие действия в пределах данного родительского компонента.

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

Теперь остановимся еще на одном свойстве любого компонента — Name (имя). По умолчанию Delphi присваивает компонентам имена, состоящие из имени типа компонента и порядкового номера. Например, «Button1», «Label1» и т.д.

 

Хороший стиль программирования

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

        

 

Итак, задайте значения свойства Caption у формы (например, «Приложение Delphi») и у кнопки (например, «Пуск»). Полезно также для тренировки изменить свойства Name кнопки и метки, хотя, конечно, в нашем простом приложении делать это не обязательно.

 

1.6 Задание обработчика события

 

Теперь все необходимые свойства компонентов заданы и осталось написать один оператор языка Pascal, чтобы при щелчке на кнопке в метке отображался какой-нибудь текст. Щелчок на кнопке, это событие, которое кнопка может обработать. Для задания обработчиков событий служит страница Events Инспектора Объектов. Выделив тот или иной компонент или форму, вы увидите на этой странице список тех событий, на которые компонент может реагировать. Практически все компоненты имеют событие OnClick, которое возникает, когда пользователь щелкнул мышью на компоненте. Для кнопки это основное событие. Так что выделите на форме вашу кнопку, перейдите в окне Инспектора Объектов на страницу событий, и найдите там строку события OnClick. Сделайте двойной щелчок на белом поле рядом с этим событием. Вы попадете в окно Редактора Кода, в котором будет видна заготовка обработчика события. Надо сказать, что для такого компонента, как кнопка, то же самое можно сделать проще: двойным щелчком на кнопке. В обоих случаях вы увидите в окне Редактора Кода текст:

 

procedure TForml.ButtonlClick (Sender: Tobject);

begin

 

end;

 

Курсор будет расположен в пустой строке между ключевыми словами begin и end. Увиденный вами код — это заготовка обработчика события, которую автоматически сделала Delphi. Вам остается только в промежутке между begin и end написать необходимые операторы.

Например, напишите в строке межу словами begin и end следующий текст:

 

Labell.Caption:='Это мое первое приложение!';

 

Таким образом, полностью ваш обработчик события должен иметь вид:

 

procedure TForml.ButtonlClick(Sender: Tobject);

begin

            Labell.Caption:='Это мое первое приложение!';

end;

 

В данном случае свойству Caption компонента Labell вы присваиваете строку текста «Это мое первое приложение!». Все указания свойств и методов производятся аналогичным образом: пишется имя компонента, затем ставится точка, а затем без пробела пишется имя свойства или метода

В приведенном операторе подразумевается, что имя метки Label1 вами не изменялось. Если вы изменили его, то вместо «Label1» надо написать введенное вами имя.

Несмотря на то, что вы еще не знакомились с языком программирования, обратите ваше внимание на одно обстоятельство. Посмотрите заголовок созданного вами обработчика события:

 

procedure TForm1.Button1Click(Sender: TObject);

 

А теперь посмотрите повыше в коде, и вы найдете похожую строку:

 

procedure Button1Click(Sender: TObject);

 

Эта строка — объявление того обработчика события, который вы создали. Обратите внимание на это обстоятельство по следующей причине. Как показывает практика, нередко можно выделить в окне Инспектора Объектов не то событие, обработчик которого нужно написать, или при выборе события выделить не тот компонент. Не удаляйте вручную неверный обработчик события. Удалите только, текст обработчика, если успели что-то написать между словами begin и end. А пустой обработчик удалит, когда придет время, сама среда Delphi. Если же вы все-таки удалили неверный обработчик события, то удалите одновременно и его объявление. Иначе вы не сможете выполнить вашу программу.

 

1.7 Компиляция и выполнение приложения

 

Итак, приложение готово. Теперь можете выполнить команду Run|Run чтобы выполнить его. Проще сделать то же самое, нажав быструю клавишу с зеленой стрелкой, направленной вправо. Еще проще нажать горячую клавишу F9. После недолгой компиляции перед вами появится окно вашего первого приложения. Нажав в нем на кнопку Пуск, вы увидите указанную вами строку текста.

         Теперь имеет смысл обсудить, что же произошло, когда вы вызвали выполнение приложения. Сначала сработал компилятор Delphi. Это программа, которая создала на основе вашего проекта исполняемый файл, имеющий имя, совпадающее с именем проекта, и расширение .exe.

Исполняемый файл содержит машинные коды и является двоичным, а не текстовым. Так что смотреть его любым текстовым редактором бессмысленно. Но любой компьютер сможет его понять и выполнить. Поэтому вы спокойно можете перенести его в другой каталог или на другой компьютер, выполнить средствами Windows и получить тот же замечательный результат, который видели при запуске из среды Delphi.

        

 

1.8            Контрольные вопросы

 

1)                 Перечислите последовательность операций при создании нового проекта.

2)                 Зачем надо давать осмысленные имена файлам проекта и модуля?

3)                 Почему нельзя файлам проекта и модуля давать одинаковые имена?

4)                 Почему в процессе проектирования полезно изменять имена компонентов, как это можно делать?

5)                 Что делать, если вы случайно закрыли окно формы, Редактора Кода или Инспектора Объектов?

6)                 Как переключиться между формой и окном Редактора Кодов с загруженным в нем текстом модуля?

7)                 Значение какого свойства надо изменить, чтобы задать надпись в заголовке окна формы, в метке, на кнопке?

8)                 Как можно в каких-то компонентах, размещенных на форме, задать полужирный шрифт (курсив, подчеркивание), оставив в других компонентах обычный шрифт?

9)                 Как изменить цвет надписи метки, кнопки?

10)            Как изменить цвет фона метки, кнопки?

 

1.9 Задания

 

1)       Создайте приложение, содержащее кнопки с надписями «Черный», «Белый», «Красный», и пусть по щелчку на них окно формы окрашивается в соответствующий цвет.

2)       В компоненте Label выведите фразу “Hello, world!!!. Перекрасьте форму в красный цвет.

3)       Выведите свои ФИО в компоненте Label. Перекрасьте форму в красный цвет.

4)       Создайте приложение, содержащее кнопку и метку. По щелчку на кнопке в метке должен отображаться текст вида «Я освоил материал первой работы на …», где вместо многоточия должна быть оценка преподавателя.

 

Лабораторная работа 2. Создание приложений с использованием функций и компонентов ввода/вывода данных.

 

Цели работы:

- познакомиться с простейшими функциями ввода/вывода данных;

- научиться создавать более сложные приложения.

 

2.1 Простейшие функции ввода/вывода данных

 

2.1.1 Ввод из окна ввода

 

         Наиболее просто программа может получить исходные данные из окна ввода. Окно ввода - это стандартное диалоговое окно, которое появляется на экране в результате вызова функции InputBox. Значение функции InputBox — строка, которую ввел пользователь.

         В общем виде инструкция ввода данных с использованием функции InputBox выглядит так:

 

Переменная := InputBox(Заголовок, Подсказка, Значение);

где:

         - Переменная - переменная строкового типа, значение которой

           должно быть получено от пользователя;

         - Заголовок - текст заголовка окна ввода;

         - Подсказка - текст поясняющего сообщения;

         - Значение - текст, который будет находиться в поле ввода, когда окно ввода появится на экране.

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

 

            s:=InputBox('Фунты-килограммы','Введите вес в фунтах','0');

 

 

Рисунок 2.1 - Пример окна ввода

        

Если во время работы программы пользователь введет строку и щелкнет на кнопке ОК, то значением функции InputBox будет введенная строка. Если будет сделан щелчок на кнопке Cancel, то значением функции будет строка, переданная функции в качестве параметра значение.

         Следует еще раз обратить внимание на то, что значение функции InputBox строкового (string) типа. Поэтому если программе надо получить число, то введенная строка должна быть преобразована в число при помощи соответствующей функции преобразования. Например, фрагмент программы пересчета веса из фунтов в килограммы, обеспечивающий ввод исходных данных из окна ввода, может выглядеть так:

     

s := InputBox('Фунты-килограммы','Введите вес в фунтах','0');

funt := StrToFloat(s);

 

2.1.2 Вывод в окно сообщения

 

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

         В простейшем случае вывести на экран окно с сообщением можно при помощи процедуры ShowMessage. Процедура ShowMessage выводит на экран окно с текстом и командной кнопкой ОК.

         В общем виде инструкция вызова процедуры ShowMessage выглядит так:

 

         ShowMessage(Сообщение);

 

где Сообщение - текст, который будет выведен в окне.

         На рисунке 2.2 приведен вид окна сообщения, полученного в результате выполнения инструкции:

 

ShowMessage('Введите вес в фунтах.');

 

 

 

 

 

 

Рисунок 2.2 - Пример окна сообщения

        

Следует обратить внимание на то, что в заголовке окна сообщения, выводимого процедурой ShowMessage, указано название приложения, которое задается на вкладке Application окна Project Options. Если название приложения не задано, то в заголовке будет имя исполняемого файла.

 

 

 

 

2.1.3 Пример использования функций ввода/вывода данных

 

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

 

procedure TForm1.Button1Click(Sender: TObject);

var

                        tenge, kurs: real;

                        doll: string;

begin

                        kurs :=150;

            doll := InputBox('Доллары - тенге','Введите количество долларов','110');

                        tenge := kurs * StrToFloat(doll);

ShowMessage ('количество тенге =' + FloatToStr(tenge));

end;

 

Результаты работы приведены на рисунках 2.3а и 2.3б.

а)                                            б)

       

                  

Рисунок 2.3 - Вид окна ввода сообщения

 

2.2. Создание приложений с помощью наиболее часто используемых компонентов ввода/вывода

 

2.2.1. Умножение двух чисел

 

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

         При построении этого приложения мы используем новые типы компонентов — окна редактирования Edit. Кроме того, для разнообразия, будем выводить результат не в метку Label, а в панель Panel, просто для того, чтобы испытать новый компонент.

         Откройте новое приложение. Перенесите на него со страницы библиотеки Standard  два окна редактирования с присоединенными к ним метками Label, одну панель Panel, одну кнопку Button и еще одну метку Label для надписи. Разместите все это примерно так, как показано на рисунке 2.4а.

         Измените надписи в метках компонентов Label на что-то осмысленное. Например, на «Число 1», «Число 2», «Результат» или на «Ширина», «Высота», «Площадь» в зависимости от того, что вы хотите понимать под соответствующими числами. Для этого измените надпись в свойстве Caption раскрывшихся списков свойств меток.

Замените свойство Caption вашей кнопки, например, на «Расчет».

В итоге ваша форма приобретет вид, показанный на рисунке 2.4б.

                            а)                                   б)                                  в)

  

                  

Рисунок 2.4 – Окно формы приложения

               

Осталось написать обработчик щелчка кнопки. Единственный оператор этого обработчика может иметь вид:

 

Panel1.Caption := Edit1.Text + ‘ * ‘ + Edit2.Text + ‘ = ‘ + FloatToStr(StrToFloat(Edit1.Text)*StrToFloat(Edit2.Text));

 

         Попробуем проанализировать этот оператор. Вы присваиваете свойству Caption компонента Panel1 значение выражения, указанного в правой части оператора. Это выражение должно иметь тип строки текста. Начинается строка с текста, введенного пользователем в окно редактирования Edit1 — этот текст хранится в свойстве Text. Затем вы прибавляете к этому тексту символы « * ». Знак «+» в выражениях для строк означает конкатенацию - сцепление двух строк символов. Затем аналогичным образом к строке добавляется текст второго окна редактирования и символы « = ». После этого мы хотим вставить в строку результат перемножения двух целых чисел. Этот результат будет числом и, чтобы вставить его в текст, надо сначала преобразовать это число в строку. Эту операцию выполняет функция FloatToStr(), которая преобразует заданный ей параметр типа действительного числа в строку символов. Осталось получить само произведение двух чисел. Но числа заданы пользователем в виде текстов - строк символов в окнах редактирования. Прежде, чем перемножать, эти строки надо перевести в числа. Эту операцию выполняют функции StrToFloat(), преобразующие символьное изображение числа в его значение типа действительного числа. Знак '*', указанный между двумя функциями StrToFloat, обозначает операцию умножения.

         Ваше приложение готово. Можете его сохранить.

Откомпилируйте свое приложение и выполните его. Убедитесь, что оно нормально работает (см. рисунок 2.4в).

 

2.2.1 Приложение с многострочным окном редактирования Memo

        

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

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

         Начните новое приложение и сохраните его. При сохранении дайте приложению имя, например, Charact..

         Перенесите на форму со страницы Standard кнопки Button и Label, а также многострочное окно редактирования Memo (шестая слева пиктограмма). Со страницы Additional перенесите два окна редактирования c присоединенными к ним метками LabeledEdit (пиктограмма с надписью «Label/аb»). Расположите эти компоненты примерно так, как показано на рисунке 2.5а. Можете изменить надписи окна приложения («Характеристики»), кнопки («Выполнить») и метки «Характеристика». Измените также надписи в метках компонентов LabeledEdit. Для этого щелкните на символе « + » в свойстве EditLabel этих компонентов и измените надпись в свойстве Caption раскрывшихся списков свойств меток. Можете также установить в форме полужирный шрифт, чтобы надписи были более четкими. Но в окне Memo шрифт надо оставить обычным (см. рисунок 2.5б).

         а)                                            б)

 

 

Рис.2.5 - Форма приложения Charact

 

         Выделите на форме одно из окон LabeledEdit и посмотрите в окне Инспектора Объектов его свойства. Главное свойство - Text. Это свойство можно задавать во время проектирования, а во время выполнения в этом свойстве можно прочитать текст, введенный пользователем. Из других свойств обратите внимание на свойство ReadOnly. Если задать его значение равным true, то пользователь сможет только читать текст в окне, но не сможет его изменять. В нашем приложении, конечно, надо оставить значение false, заданное по умолчанию в этом свойстве.

         Теперь выделите компонент Memo1 и посмотрите его свойства. Основное свойство - Lines. Вы можете увидеть в окне Инспектора Объектов около этого свойства его тип - TStrings. Запомните этот тип. Он очень часто будет встречаться вам при работе с Delphi. В процессе проектирования значения свойств этого типа можно задавать, нажав кнопку с многоточием около свойства в окне Инспектора Объектов. Откроется окно редактора строк, показанное на рисунке 2.6. В нем вы можете записать какой-то текст, который будет показан пользователю в первый момент при запуске приложения. Но в нашем примере никакого текста писать не надо. Наоборот, надо стереть текст «Memol», заданный по умолчанию.

         Во время выполнения приложения для удаления текста из окна надо выполнить процедуру Clear. Этот метод относится к самому окну, а не к его свойству Lines. Так что оператор

 

            Memol.Clear;

 

удалит текст из окна Memo1.

 

 

Рисунок 2.6 - Окно редактора строк

 

         Для занесения новой строки в конец текста окна редактирования можно воспользоваться методами Add или Append свойства Lines. В качестве аргументов в эти методы передается строка текста. Например, оператор

 

Memol.Lines.Add('XАРАКТЕРИСТИКА');

 

занесет в окно строку с текстом «ХАРАКТЕРИСТИКА». Строки текста, как вы видите в приведенном выше операторе, заключаются в одинарные кавычки.

         Окно Memo имеет, как и окно LabeledEdit, свойство ReadOnly - только для чтения. Если окно используется только для отображения информации, то это свойство надо установить в true. Но в нашем примере предполагается, что кто-то может написать в этом окне характеристику. Так что значение ReadOnly должно быть равно false.

         Свойство Alignment определяет выравнивание текста в окне и может принимать значения taLeftJustify - влево, taRightJustify — вправо, taCenter — по центру. По умолчанию задано значение taLeftJustify, но, вероятно, в нашем примере лучше установить значение taCenter.

         Свойство ScrollBars управляет появлением в окне полос прокрутки. Оно может принимать следующие значения: ssNone - полос прокрутки нет, ssHorizontal или ssVertical - включена соответственно горизонтальная или вертикальная полоса, ssBoth - включены обе полосы. Если вы хотите дать возможность пользователю писать длинные характеристики, вероятно, имеет смысл задать ScrollBars равным ssVertical, чтобы включить вертикальную полосу, облегчающую прокрутку текста.

         Теперь вы можете написать обработчик щелчка на кнопке. Пусть такой щелчок будет выводить в окно Memo1 шапку характеристики того, чьи фамилия, имя и отчество занесены в окна редактирования. В приведенном ниже коде предполагается, что это студент. Но вы, конечно, можете заменить слово «Студент» на «Сотрудник» или «Учащийся» - т.е. на то, что вам больше подходит. Обработчик щелчка на кнопке может иметь следующий вид:

 

            procedure TForml.ButtonlClick(Sender: Tobject);

            begin

                        Memo1.Clear;

                        Memo1.Lines.Add('XАРАКТЕРИСТИКА');

                        Memo1.Lines.Add('');

            Memo1.Lines.Add('Студент ' + LabeledEdit1.Text + ' '

+ LabeledEdit2.Text);

                        Memo1.SetFocus;

            end;

        

Первый оператор этого кода очищает окно Memo1. Второй — заносит в окно заголовок «XАРАКТЕРИСТИКА». Третий оператор переводит текст на новую строку. Четвертый - комбинирует из текстов, введенных пользователем в окна LabeledEdit1 и LabeledEdit2, строку вида «Студент». Как видно, соединение нескольких строк в одну осуществляется просто операцией сложения. К строке «Студент » (она должна кончаться пробелом, чтобы это слово не слилось с фамилией) добавляется текст окна LabeledEdit1, затем добавляется строка пробела, и к этому добавляется текст окна LabeledEdit2.

         Последний не обязательный оператор методом SetFocus переводит фокус на компонент Memo1. Так что пользователь немедленно может начать писать текст характеристики.

         Сохраните ваше приложение и выполните команду Run | Run. Если вы все сделали аккуратно, то после успешной компиляции вы увидите окно вашего выполняющегося приложения и сможете убедиться, что оно работает правильно (см. рисунок 2.7).

 

Рисунок 2.7 - Приложение Charact во время выполнения

2.3. Задания

 

1)       Выведите в окне ввода какую-либо фразу с помощью функции InputBox.

2)       Выведите в окне сообщения какую-либо фразу с помощью процедуры ShowMessage.

3)       Выведите в окне ввода какую-либо фразу с помощью функции InputBox, причем она должна содержать числовое значение, взятое из компонента Edit.

4)       Выведите в окне сообщения какую-либо фразу с помощью процедуры ShowMessage, причем она должна содержать числовое значение, взятое из компонента Edit.

5)       Выведите текст из десяти строк в компоненте Memo. В другом компоненте Memo выведите эти десять строк в обратном порядке.

6)      Введите в компонент Memo следующий текст:

                   Первое число: 1

                        Второе число: 2

                        Сумма: 3

          С помощью компонентов: Edit, Label, Button; оформите программу. На другой форме с помощью этих компонентов проверьте правильность вычислений

         Лабораторная работа 3. Структуры выбора

 

Цели работы:

- познакомить с использованием операторов выбора;

- научить использовать компоненты для создания приложений.

        

         3.1 Управляющие структуры

 

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

         Последовательная структура встроена в Pascal. Если не указано иначе, компьютер автоматически выполняет операторы Pascal один за другим в порядке их записи.

         Структуры выбора используются для избрания одного из альтернативных направлений действий.

         Структура повторения – это многократное повторение одних и тех же действий для решения задачи. На практике это реализуется либо с помощью рекурсии либо с помощью итерации. Итерация — это повторение одних и тех же действий определенное количество раз. Основным методом итерации является цикл.

 

         3.2 Операторы выбора в Pascal

    

В Pascal есть два условных оператора: if и case.

 

3.2.1 Операторы if

 

Синтаксис простой формы оператора if, называемой if-then, имеет вид:

 

if   условие   then begin

            [операторы; ]

end;

 

Все операторы между ключевыми словами begin и end выполняются, только если; значение выражения условие равно True. Выражение условие должно иметь булев тип.

Условный оператор if (если) очень похож на сослагательное наклонение в естественном языке. Рассмотрим следующее предложение с ключевым словом "если":

 

"Если в предыдущих партиях игры в гольф мое среднее количество ударов (myAverageScore) меньше вашего (yourAverageScore) на величину более 10, то в следующей партии я даю вам фору (handicap) 5 очков".

 

Это предложение непосредственно преобразуется в код Pascal путем замены ключевого слова "если" оператором if.

 

Пример 3.1. Создать приложение, используя нижеприведенный код.

 

handicap := 0; 

difference := yourAverageScore - myAverageScore;

if (difference >= 10) then begin

            handicap := 5;

end;

 

В некоторых случаях необходима более сложная структура принятия решения, чем предоставляемая простым оператором if-then. Рассмотрим следующее предложение:

 

"Если в предыдущих партиях игры в гольф мое среднее количество ударов (myAverageScore) меньше вашего (yourAverageScore) на величину более 10 очков, то в следующей партии я даю вам фору (handicap) 5 очков, в противном случае — очка".

 

Для вычисления форы на следующую партию в исходном коде понадобится более сложный оператор if-then-else (если-то-иначе), синтаксис которого имеет вид

 

if условие then begin

            [операторы1; ]

end

else begin

            [операторы2;

end;

 

Пример 3.2. Создать приложение, используя нижеприведенный код, реализующий усложненный пример.

 

difference := yourAverageScore - myAverageScore;

if (difference >= 10) then begin

            handicap := 5;

end

else begin

            handicap := 2;

end;

           

Обратите внимание: я всегда даю вам фору, как минимум, 2 очка, даже если вы играете лучше. Чтобы устранить это противоречие, еще раз изменим условия игры.

 

"Если в предыдущих партиях игры в гольф мое среднее количество ударов (myAverageScore) меньше вашего (yourAverageScore) на величину более 10 очков, то в следующей партии я даю вам фору (handicap) 5 очков. Если разница (difference) лежит в диапазоне от 7 до 9 очков, то я даю вам фору 3 очка. Если разница лежит в диапазоне от 4 до 6 очков, то я даю вам фору 2 очка. В противном случае в следующей партии никакой форы нет".

 

Для вычисления форы на следующую партию теперь понадобится еще более сложная форма оператора if-then-else, синтаксис которой имеет вид

 

if условие1 then begin

            [операторы1;]

end

else  if условие2 then begin

            [операторы2; ]

end

.

.

.

else  if yсловиеN then begin

            [операторыN; ]

end

else begin

            [операторыХ;]

end;

 

В приведенном ниже фрагменте кода, вычисляющем фору в последней версии игры в гольф, выполняется только один оператор присваивания значения переменной handicap. Присваивание выполняется в зависимости от значения переменной difference. Проследите за работой этого кода и определите, что происходит, когда значение difference равно 15, 8,4 и 1.

 

Пример 3.3. Создать приложение, используя нижеприведенный код.

 

difference := yourAverageScore - myAverageScore;

if (difference >= 10) then begin

            handicap := 5 ;

end

else if (difference >= 7) then begin

            handicap := 3;

end

else if (difference >= 4) then begin

            handicap := 2;

end

else begin

            handicap := 0;

end;

 

 

 

 

 

3.2.1 Операторы case

 

Другая структура принятия решений в Pascal — оператор case. Каждый оператор case можно заменить эквивалентным ему оператором if, однако обратное неверно — не всякий оператор if можно заменить эквивалентным case. Тем не менее оператор case используется довольно часто и поддерживается почти во всех языках высокого уровня. Общий синтаксис оператора case имеет вид

 

case управляющее_выражение of

            список_значений_1: begin

                                                                       операторы 1;

                                                           end;

            список_значений_2: begin

                                                                       операторы2 ;

                                                           end;

            .

            .

            .

            список_значений_N:            begin

                                                                       операторыN;

                                                           end ;

            else begin

                        операторыХ;

            end;

            end;

 

В этом синтаксисе управляющее выражение сравнивается с выражениями каждого списка. Оно должно быть выражением порядкового типа, т.е. типа Integer, Char, Boolean или других подобных типов. Кроме того, каждое выражение в списках должно быть порядковым и вычисляемым во время компиляции. Например, в списках допустимы выражения 12, True, 4 - 9  или Integer('Z').

Список выражений может также содержать поддиапазон, имеющий форму первое_выражение..последнее_выражение, оба из которых должны быть порядковыми, причем первое_выражение <= последнее_выражение. И наконец, список_выражений может быть представлен в форме выражение 1, выражение2,..., выражениеN, в которой каждое выражение является порядковым выражением или поддиапазоном порядковых выражений.

Оператор case может содержать любое количество списков выражений и только одно предложение else. Выполнение оператора case аналогично выполнению структуры if-then-else. Если значение управляющего выражения совпадает с любым выражением из какого-либо списка, то выполняются операторы этого списка. Затем управление передается на оператор, следующий за оператором case (происходит выход из оператора case). Если управляющее выражение совпадает с выражениями, присутствующими в нескольких списках, то выполняются операторы самого верхнего из этих списков. Если управляющее выражение не совпадает ни с одним из выражений в списках, то выполняются операторыХ предложения else. Включение предложения else в оператор case не обязательно, однако оно гарантирует, что код обработает любое непредвиденное значение управляющего выражения. Если управляющее выражение не совпадает ни с одним из выражений в списках и предложение else отсутствует, то не выполняется ни один оператор и происходит выход из оператора case.

Операторы case можно вкладывать друг в друга аналогично вложенным операторам if. Каждый вложенный оператор case должен иметь ассоциированное с ним ключевое слово end.

Рассмотрим использование оператора case на примере условий игры в гольф. Заменим в предыдущих примерах операторы if эквивалентными конструкциями case. Но сначала придется сделать несколько предположений относительно счета в гольфе.

 

Предположим, что количество ударов по каждой лунке изменяется от 1 до 8. Тогда минимальный счет в партии на 18 лунок равен 144 (умножаем 8 ударов на 18 лунок), а минимальный — 18 (один удар на каждую лунку). Максимальная разница ударов двух игроков равна 144 — 18 = 126. В зависимости от того, кто лучше играет в гольф, разница может быть положительной или отрицательной.

 

В следующем фрагменте кода, вычисляющем фору с помощью оператора case, иллюстрируется использование списков и поддиапазонов.

 

Пример 3.4. Создать приложение, используя нижеприведенный код.

 

difference := yourAverage - myAverageScore;

case difference of

            4, 5, 6: begin

                                               handicap := 2;

                                   end;

            8, 9: begin

                                   handicap:=3;

                        end;

            10..126: begin

                                               handicap :=5;

                                   end;

            else begin

                        handicap := 0;

            end;

end;

 

3.2 Примеры использования инструкции if с компонентами

 

Программирование в Delphi: разработка интерфейса

Структуры принятия решений обычно используются с такими компонентами интерфейса, как переключатели (TRadioButton) и флажки (TCheckBox). Переключатели предоставляют пользователю возможность выбрать один элемент из списка нескольких элементов, а флажки - выбрать из списка один или несколько элементов.

3.2.1 Использование флажка

 

Компонент флажок (TCheckBox) предоставляет пользователю два варианта выбора — его можно установить или снять. Установленный флажок отмечен крестиком, у снятого флажка квадратик пустой. Пользователь может переключить флажок с помощью мыши или клавиши пробела. Для переключения клавишей пробела флажок должен иметь фокус ввода. Когда флажки объединены в группу, пользователь  может установить  или  снять любые флажки группы.

Свойство Caption этого компонента содержит текст, расположенный справа от флажка. Свойство Checked, имеющее тип Boolean, определяет установлен ли флажок по умолчанию. Если свойство AllowGrayed имеет значение True, то флажок может находиться в одном из трех состояний: установленном, снятом и затененном. Свойство State определяет состояние флажка— установленный (cbChecked), снятый (cbUnchecked) или затененный (cbGrayed). Ниже (см. листинг 3.1) приведен пример кода, в котором используются флажки. Выполнение этого кода показано на рисунке 3.1. Обратите внимание: свойство Name содержит префикс chk, указывающий на то, что это флажок.

 

         

 

Рисунок 3.1 - Пример использования флажков

 

 

Листинг 3.1. Пример использования флажков

procedure TForm1.Button1Click(Sender: TObject);

var

            used : Boolean;

begin

            used := false;

            Memo1.Clear;

Memo1.Lines.Add('Вы используете следующие кредитные

            карточки; '+ #13);

            TestCard(CheckBox1,used);

            TestCard(CheckBox2,used);

            TestCard(CheckBox3,used);

            TestCard(CheckBox4,used);

            if not(used) then begin

                        Memo1.Lines.Add('Кредитных карточек у вас нет!');

            end;

end;

procedure TForm1.TestCard(Sender: TObject;

                                                                                  var used : Boolean);

begin

   with (Sender as TCheckBox) do

   begin

    if Checked then begin

                        Memo1.Lines.Add(Caption);

                        used := true;

            end;

   end;

end;

 

3.2.2 Использование переключателей

 

В отличие от флажков, позволяющих пользователю выбрать один или несколько вариантов, переключатели (TRadioButton) позволяют выбрать только один из предложенных вариантов. Переключатели группируются путем размещения их в контейнерном объекте - форме, объединении элементов (TgroupBox), панели или фрейме. Все переключатели в одном контейнере работают как одна группа. Чтобы сгруппировать переключатели в объединении элементов или на панели, необходимо сначала разместить на форме объединение элементов или панель, а затем расположить переключатели внутри этих контейнерных объектов.

         Когда пользователь устанавливает один из переключателей, все остальные переключатели группы автоматически снимаются. Состояние переключателя содержится в свойстве Checked: если оно равно True, то переключатель установлен, а если False — снят. Свойство Caption содержит текст, видимый справа от переключателя. Ниже (см. листинг 3.2) приведен пример кода, в котором используются переключатели. Выполнение кода показано на рисунке 3.2.

 

Листинг 3.2 Пример использования переключателей

procedure TForm1.EvaluateClick(Sender: TObject);

var

lineOut : String;

begin

Memo1.Clear;

if RadYes.Checked then begin

lineOut := 'Я очень рад за вас!';

end

else if RadNo.Checked then begin

lineOut := 'Почему? Ведь это так интересно!';

end

else begin

lineout :='Да или нет?';

end;

Memo1.Lines.Add(lineOut);

end;

      

Рисунок 3.2 - Пример с переключателями

 

3.2.3 Использование переключателей и флажков

 

Данный пример иллюстрирует использование переключателей и флажков в структурах принятия решений. Выполнение кода рассматриваемого примера показано на рисунке 3.3.

В этом примере пользователь с помощью переключателя и флажков устанавливает качества, которые, по его мнению, правильно характеризуют его личность - Мужчина, Женщина, Умный, Инициативный, Дружелюбный, Трудолюбивый. После этого пользователь щелкает на кнопке Дать характеристику, и программа выводит в области просмотра Memo1 краткую характеристику пользователя.

 

 

Рисунок 3.3 - Пример программы с переключателями и флажками

 

Листинг 3.3 Пример использования переключателей и флажка

procedure TForm1.Button1Click(Sender: TObject);

var

none: Boolean;

begin

Memo1.Clear;

if radMale.Checked then begin

Memo1.Lines.Add('Ваш пол мужской.');

end

else if radFeMale.Checked then begin

Memo1.Lines.Add('Ваш пол женский.');

end

else begin

Memo1.Lines.Add('Вы не ввели свой пол.');

end;

Memo1.Lines.Add('');

Memo1.Lines.Add('Ваши качества');

none := True;

if chkIntelligent.Checked then begin

Memo1.Lines.Add('Умный');

none := False;

end;

if chkEnthusiastic.Checked then begin

Memo1.Lines.Add('Инициативный');

none := False;

end;

if chkFriendly.Checked then begin

Memo1.Lines.Add('Дружелюбный');

none := False;

end;

if chkHardWork.Checked then begin

Memo1.Lines.Add('Трудолюбивый');

none := False;

end;

if none then begin

memo1.Lines.Add('Никакие качества не введены.');

end;

end;

 

3.3 Контрольные вопросы

 

1)      Приведите синтаксис и опишите действия, выполняемые операторами if и case, в самом общем виде.

2)      Что такое вложенные структуры выбора?

 

3.4 Задания

 

1)     С помощью структуры if..then посчитать сумму нечетных чисел меньших n, если n>10; в противном случае посчитать сумму четных чисел.

2)     Преобразовать оператор if в оператор case в следующем коде:

         if (ave >= 0.90)   then begin

                        letterGrade := 'A';

            end;

            else if (ave >= 0.80) then begin

                        letterGrade := 'B';

            end

            else if (ave >= 0.70) then begin

                        letterGrade := 'С;

            end

            else if (ave >= 0.60) then begin

                        letterGrade := 'D';

            end;

         Лабораторная работа 4. Циклические структуры.

 

Цели работы:

- познакомить с использованием операторов цикла;

- научить использовать компоненты для создания приложений;

        

В языке Pascal программисту предоставлены три вида операторов цикла: for, while и repeat.

 

4.1 Циклы for

 

Цикл for называется детерминированным. Это означает, что он может быть использован, только если количество итераций цикла можно определить до начала его выполнения. Синтаксис инкрементного цикла for имеет вид

 

for счетчик := начало to конец do begin

                        [операторы; ]

end;

 

Переменная счетчик называется счетчиком цикла. Она должна быть локальной переменной любого порядкового типа. Выражения начало и конец определяют первое и последнее значение переменной счетчик. Тип выражений начало и конец должен быть coвместимым по присвоению с типом переменной счетчик. Значение  выражения начало должно быть меньше, или равно значению выражения конец, в противном случае операторы внутри цикла (в теле цикла) не будут выполнены ни разу. После выполнения цикла (после очередной итерации) инкрементный цикл for автоматически увеличивает значение переменной счетчик на единицу (или на одну порядковую позицию). Затем управление передается в заголовок цикла и счетчик сравнивается с выражением конец. Если счетчик меньше или равен выражению конец, то тело цикла выполняется повторно, в противном случае управление передается на оператор, следующий за оператором for, т.е. происходит выход из цикла.

В следующем фрагменте кода инкрементный цикл for используется для вычисления суммы целых чисел от 1 до 100:

 

Пример 4.1. Использование инкрементного цикла for

var

            counter : Integer;

            sum : Integer;

begin

            sum := 0;

            for counter := 1 to 100 do begin

                        sum := sum + counter;

            end;

end;

 

После выхода из цикла переменная sum содержит сумму целых чисел от 1 до 100, равную 5050.

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

 

for счетчик  := начало downto конец do begin

            [операторы; ]

end;

 

Как и раньше, переменная счетчик является счетчиком цикла, а выражения начало и конец определяют первое и последнее значения переменной счетчик. Однако есть и существенное отличие: в декрементном цикле значение начало должно быть больше или равно значению конец, иначе тело цикла не выполнится ни разу. После выполнения тела цикла счетчик автоматически уменьшается на единицу (или до предыдущей порядковой позиции). Если при этом счетчик больше или равен значению выражения конец, то выполняется тело цикла, в противном случае происходит выход из цикла.

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

           

Пример 4.2. Использование декрементного цикла for

var

            counter : Integer;

            sum : Integer;

begin

            sum := 0;

            for counter := 100 downto 1 do begin

                        sum := sum + counter;

            end;

end;

 

Как и операторы if, циклы for могут быть вложенными. Счетчик каждого вложенного цикла должен иметь уникальное имя. В следующем фрагменте кода вложенные циклы for используются для вывода в область просмотра Memo1 таблицы умножения размером 12x12.

 

Пример 4.3. Вывод таблицы умножения размером 12*12

var

            row, col : integer;

            lineOut, product : string;

begin

            Memo1.Clear;

            Memo1.Lines.Add('');

            for row := 1 to 12 do begin

                        lineout :='';

                        for col := 1 to 12 do begin

                                   product:=IntToStr(row * col) + ' ';

                                   lineOut := lineOut + product;

                        end;

                        Memo1.Lines.Add( lineOut);

            end;

end;

 

Рисунок 4.1 – Пример использования вложенных операторов for

 

Следующий пример демонстрирует использование в качестве счетчика переменной символьного типа. Запомните: счетчик не обязательно должен иметь тип Integer, он может иметь любой порядковый тип. В этом примере в строковую переменную alphabet записываются все буквы в нижнем регистре:

 

Пример 4.4. Использование символьной переменной в качестве

счетчика

var

            letter : Char;

            alphabet : String;

begin

            alphabet := '';

            for letter := 'a' to 'z' do begin

                        alphabet := alphabet + ' ' +letter;

            end;

            Label1.Caption := alphabet;

end;

 

В следующем примере в циклах for используются как целочисленные, так и символьные счетчики.

 

Пример 4.5. Использование целочисленных и символьных счетчиков

const

            NUMLINES      = 10;

            DISPLAY_CHAR  = 'I';

            SPACE    = ' ';

var

            lineOut: String;

            lineNum: Integer;

            letterNum: Integer;

            letterVal: Integer;

            letter: Char;

begin

            Memo1.Clear;

            for lineNum := NUMLINES downto 1 do begin

                        lineOut := '';

                        for letterNum :=1 to lineNum do begin

                                   lineOut := lineOut +DISPLAY_CHAR;

                        end;

for letterNum := 1 to (2*(NUMLINES-lineNum)) do begin

                                   lineOut := lineOut + SPACE;

                        end;

                        for letterNum :=1  to lineNum do begin

                                   lineOut := lineOut +DISPLAY_CHAR;

                        end;

                        Memo1.Lines.Add(lineOut);

            end;

            letterVal := 62;

            for lineNum := 1 to NUMLINES do

            begin

                        lineOut := '';

                        for letter := Chr(letterVal) to

                                   Chr(letterVal+(2*NUMLINES)-1) do

                        begin

                                   lineOut := lineOut +letter;

                        end;

                        Memo1.Lines.Add(lineOut);

                        letterVal := letterVal +1;

            end;

end;

 

После выполнения этого фрагмента кода в области просмотра  Memo1 появляется картина, составленная из символов (см. рисунок 4.2).

 

 

Рисунок 4.2

 

4.2 Циклы while и repeat

 

Циклы while и repeat являются недетерминированными. Это означает, что количество итераций не обязательно должно быть известно до начала выполнения цикла. Циклы while и repeat можно также использовать вместо for в качестве детерминированных. Таким образом, каждый цикл for можно заменить эквивалентным ему циклом while или repeat, но не наоборот. Используемые в Pascal циклы while и repeat имеют аналоги почти во всех языках высокого уровня.

Синтаксис цикла while имеет вид:

 

while условие do begin

            [операторы; ]

end;

 

Синтаксис цикла repeat имеет вид

 

repeat

            [операторы; ]

until условие;

 

Выражение условие должно быть булева типа. Тело цикла while выполняется, если значение: условия равно True. В то же время тело цикла repeat выполняется, если значение условие равно False. В этих циклах (в отличие от for) в теле цикла могут явно изменяться переменные, входящие в выражение условие, которое в этом случае называется управляющим выражением. Если условие в теле цикла не изменяется, то while или repeat превращается в бесконечный цикл.

Обратите внимание: в приведенном выше синтаксисе ключевые слова begin и end oгpaничивают тело цикла while, но не цикла repeat. Тело цикла repeat составляют все операторы, расположенные между ключевыми словами repeat и until.

Существует еще одно важное отличие между циклами while и repeat: тело цикла геpeat всегда выполняется, как минимум, один раз, в то время как тело цикла while может не выполниться ни разу. Поэтому цикл repeat легко преобразовать в цикл while, однако обратное преобразование — более сложная задача. Тот фактор, что тело цикла while может оказаться не выполненным ни разу, придется учитывать с помощью дополнительного условия if, проверяющего условие в начале цикла. Естественно, такая проверка избыточна: программист вынужден дважды вводить один и тот же код условия. Поэтому данный фактор является основным условием выбора между циклами while и repeat: если тело цикла всегда должно быть выполнено хотя бы один раз, то предпочтителен цикл repeat, в противном случае более удобен цикл while.

В качестве примера использования циклов while и repeat запишем с их помощью код вычисления суммы целых чисел от 1 до 100:

Пример 4.6. Использование цикла while.

var

            sum,count: integer;

begin

            sum:= 0;

            count := 1;

            while (count <= 100) do begin

                        sum:= sum + count;

                        count := count + 1;

            end;

            Label1.Caption := IntToStr(sum);

end;

 

Пример 4.7. Использование цикла repeat.

var

            sum,count: integer;

begin

            sum:= 0;

            count := 1;

            repeat

                        sum:= sum + count;

                        count := count + 1;

            until (count > 100);

            Label1.Caption := IntToStr(sum);

end;

 

Рассмотрим еще один пример использования недетерминированных циклов. Допустим, что для получения доступа к системе пользователь должен ввести правильный пароль — Borland. В приведенном ниже фрагменте кода пользователю предоставляется для этого три попытки. Выход из цикла происходит, если пользователь введет правильный пароль или исчерпает количество попыток. Следующий за циклом оператор if проверяет, какое из этих двух событий произошло. Обратите внимание: пароль чувствителен к регистру символов.

 

Пример 4.8. Усложненный пример недетерминированных циклов

const

            PASSWORD ='Borland'; // Пароль чувствителен к регистру!

            MAX_TRY =3;

var

            tries : integer;

            passwd: string;

begin

            tries := 1;

            passwd:= '';

            while (passwd <> PASSWORD)and (tries <=MAX_TRY) do

            begin

passwd := InputBox(' ВВЕДИТЕ ПАРОЛЬ (Попытка № '

            + IntToStr(tries) + ')' , 'Пароль?', ‘’);

                        Inc(tries);

            end;

            if (passwd = PASSWORD) then begin

ShowMessage ('Вы ввели правильный пароль'

+ 'ДОСТУП ПРЕДОСТАВЛЕН’);

            end

            else begin

                        Beep;

ShowMessage('Неправильный пароль.’ +

            В ДОСТУПЕ ОТКАЗАНО');

                        Application.Terminate;

            end;

            ShowMessage('Добро пожаловать в программу!')

            {Здесь располагается остальная часть программы}

end;

 

4.3. Контрольные вопросы

 

1)     Опишите синтаксис циклов for, while и repeat и выполняемые ими операции.

2)     Существует ли для каждого цикла for эквивалентный ему цикл while или repeat? Если нет, то почему?

3)     Существует ли для каждого цикла while или repeat эквивалентный ему цикл for? Если нет, то почему?

4)     Можно ли каждый цикл while заменить эквивалентным ему циклом repeat? Если нет, то почему?

 

4.4. Задания

 

1)       С помощью цикла Repeat выведите произведение чисел от 1 до 10 делящихся на три.

2)       С помощью цикла For выведите числа от 1 до 10 в обратном порядке и посчитайте их сумму.

3)       Следующий фрагмент кода записывает в строку alphabet буквы английского алфавита. В приведенном фрагменте используется цикл while. В качестве упражнения напишите эквивалентный код с циклом repeat.

 

var

            letter: Char;

            alphabet: String;

begin

            alphabet := '';

            letter := 'a';

            while (letter <= 'z') do begin

                        alphabet := alphabet + letter;

                        letter := Succ(letter);

            end;

end;

Лабораторная работа 5. Операции с массивами.

 

Цели работы:

                - познакомить с основными операциями с массивами;

- научить выполнять операции с массивами с использованием компонента StringGrid.

 

5.1 Определение массива

 

Массив — это структура данных, позволяющий хранить под одним именем совокупность данных некоторого типа Синтаксис объявления одномерного массива выглядит так:

 

var имя массива: array [диапазон] of тип элементов;

 

Например, предложение:

 

            var A: array [1..10] of integer;

 

объявляет массив с именем А, содержащий 10 целых чисел.

         Доступ к элементам массива осуществляется по имени массива и через индексы. Например,

           

A[5]:=7;

           

Диапазон индексов совершенно не обязательно должен начинаться с 1. Например, можно объявить массив следующим образом:

        

var В: array [0..10] of integer;

           

Поскольку индексы изменяются от 0 до 10, то в таком массиве 11 чисел.

Объявление переменной типа массива можно совмещать с заданием элементам массива начальных значений. Эти значения перечисляются после знака равенства, разделяются запятыми и заключаются в круглые скобки. Например:

 

Var Al:array[0..10] of integer = (1,2,3,4,5,6,7,8,9,10,11);

           

         Можно объявлять многомерные массивы, т.е. массивы, элементами которых являются массивы. Например, двумерный массив можно объявить таким образом:

 

Var A2: array[1..10, 1..3] of integer;

 

Этот оператор описывает двумерный массив, который можно представить себе как таблицу, состоящую из 10 строк и 3 столбцов.

Доступ к значениям элементов многомерного массива обеспечивается через индексы, перечисляемые через запятую. Например, А2[4,3] — значение элемента, лежащего на пересечении четвертой строки и третьего столбца.

Так же, как и в случае одномерных массивов, объявление переменной типа массива можно совмещать с заданием элементам массива начальных значений. Например:

 

             

            var A1 array [1..4, 1..3] of integer = (        

(1, 2, 3),

                                                                                                          (4, 5, 6),

                                                                                                          (7, 8, 9),

                                                                                                          (10, 11, 12)    

                                                                                                          );

            При задании начальных условий список значений по каждой размерности заключается в скобки. Приведенный выше пример типизированной константы создает двухмерный массив A3.Например, элемент А3[1,2] равен 2, элемент А3[4,1] равен 10 и т.д.

 

5.2. Операции с массивами

        

Типичными операциями при работе с массивами являются:

- вывод массива;

- ввод массива;

- поиск максимального или минимального элемента массива;

- поиск заданного элемента массива;

- сортировка массива.

 

5.2.1 Вывод массива

Под выводом массива понимается вывод на экран монитора (в диалоговое окно) значений элементов массива.

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

         В качестве примера на рисунке 5.1 приведено диалоговое окно приложения, которое демонстрирует инициализацию и процесс вывода значений элементов массива в поле метки (Label1). Программа выводит пронумерованный список футбольных команд. Следует обратить внимание, что для того чтобы список команд выглядел действительно как список, свойству Label1.AutoSize нужно присвоить значение False. Фрагмент текста программы приведен в листинге 5.1.

       

 

Рисунок 5.1 - Форма и диалоговое окно приложения Вывод массива

 

Листинг 5.1. Инициализация и вывод массива

const  

                        NT = 5;

var

                        team: array[1..NT] of string[10] =                                                                                             ('Зенит','Динамо','Ротор','Спартак','CКA');

procedure TForml.ButtonlClick(Sender: TObject);

var

                        st:string;  // список команд

                        i:integer; // индекс, номер элемента массива

begin

                        // формирование списка для отображения в форме

                        st:=’’;

                        for i:=l to NT do

                                   st := st + IntToStr(i)+ '  '+ team[i] + #13;

                        // вывод списка

                        Label1.Caption := st;

end;

 

5.2.2 Ввод массива.

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

         Для ввода массива удобно использовать  компонент StringGrid. Значок компонента StringGrid находится на вкладке Additional.

         Компонент StringGrid представляет собой таблицу, ячейки которой содержат строки символов. В таблице 5.1 перечислены некоторые свойства компонента StringGrid.

В качестве примера использования компонента StringGrid для ввода массива рассмотрим программу, которая вычисляет среднее арифметическое значение элементов массива. Диалоговое окно программы приведено на рисунке 5.2. Компонент StringGrid используется для ввода массива, компоненты Label1 и Label2 — для вывода пояснительного текста и результата расчета, Button1 — для запуска процесса расчета.

Добавляется компонент StringGrid в форму точно так же, как и другие компоненты. После добавления компонента к форме нужно выполнить его настройку в соответствии с таблицей 5.2. Фрагмент текста программы приведен в листинге 5.2.

 

Таблица 5.1 - Свойства компонента StringGrid

Свойство                            

Определяет

Name                                    

Имя компонента. Используется в программе для доступа к свойствам компонента

ColCount             

Количество колонок таблицы

RowCount           

Количество строк таблицы

Cells                                     

Соответствующий таблице двумерный массив. Ячейка таблицы, находящаяся на пересечении столбца номер col и строки  номер row определяется элементом cells[col,row]

FixedCols                             

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

FixedRows                           

Количество зафиксированных сверху строк таблицы. Зафиксированные строки выделяются цветом и при вертикальной прокрутке таблицы остаются на месте

Options.goEditing             

Признак допустимости редактирования содержимого ячеек таблицы. True - редактирование разрешено, False - запрещено

Options.goTab                   

Разрешает (True) или запрещает (False) использование клавиши <Таb> для перемещения курсора в следующую ячейку таблицы

Options.GoAlways-        ShowEditor

Признак нахождения компонента в режиме редактирования. Если значение свойства False, то для того, чтобы в ячейке появился курсор, надо начать набирать текст, нажать клавишу <F2> или сделать щелчок мышью

 

 

 

        

 

Рисунок 5.2 - Диалоговое окно программы Ввод и обработка массива

 

Таблица 5.2 Значения свойств компонента StringGrid1

Свойство

Значение

ColCount

5

FixedCols

0

RowCount

1

Options.goEditing

True

Options.AlwaysShowEditing

True

Options.goTabs

True


 

 

Листинг 5.2. Ввод и обработка массива целых чисел

procedure TForml.ButtonlClick(Sender: TObject);

var

                        a: array[1..5] of integer; // массив

                        summ: integer; // сумма элементов

                        sr: real; // среднее арифметическое

                        i: integer; // индекс

begin

            {ввод массива: считаем, что если ячейка пустая,

            то соответствующий ей элемент массива равен нулю}

            for i:= 1 to 5 do

            if Length(StringGridl.Cells[i-l,0]) <> 0

                        then a[i] : = StrToInt(StringGridl.Cells[i-1, 0])

            else a[i] : = 0 ;

            // обработка массива

            summ := 0;

            for i :=1 to 5 do

                        summ := summ + a[i];

                        sr := summ / 5;

                        // вывод результата

Label2.Caption := 'Сумма элементов: ' + IntToStr(summ) + #13+'Среднее арифметическое: ' + FloatToStr(sr);

end;

 

5.2.3 Поиск минимального (максимального) элемента массива

Задачу поиска минимального элемента массива рассмотрим на примере массива целых чисел. Алгоритм поиска минимального (максимального) элемента массива довольно очевиден: сначала делается предположение, что первый элемент массива является минимальным (максимальным), затем остальные элементы массива последовательно сравниваются с этим элементом. Если во время очередной проверки обнаруживается, что проверяемый элемент меньше (больше) принятого за минимальный (максимальный), то этот элемент становится минимальным (максимальным) и продолжается проверка оставшихся элементов.

         Диалоговое окно приложения поиска минимального элемента массива содержит соответствующим образом настроенный компонент StringGrid, который применяется для ввода элементов массива, два поля меток (Label1 и Label2), использующиеся для вывода информационного сообщения и результата работы программы, и командную кнопку (Button1), при щелчке на которой выполняется поиск минимального элемента массива. Значения свойств компонента StringGrid1 такие же, что и приведены в таблице 5.2 .

         В листинге 5.3 приведена процедура обработки события OnClick для командной кнопки Button1, которая вводит массив, выполняет поиск минимального элемента и выводит результат — номер и значение минимального элемента массива.

 

Листинг 5.3. Поиск минимального элемент массива

procedure TForml.ButtonlClick(Sender: TObject);

const

                        SIZE=5;

var

                        a:array[1..SIZE]of integer; // массив целых

                        min:integer; // номер минимального элемента массива

i:integer; // номер элемента, сравниваемого с

//минимальным

begin

// ввод массива

                        for i:=l to SIZE do

                                   a[i]:=StrToInt(StringGridl.Cells[i-l,0]) ;

                        // поиск минимального элемента

                        min:=l;  // пусть первый элемент минимальный

                        for i:=2 to SIZE do

                                               if a[i]< a[min] then min:=i;

                        // вывод результата

label2.caption:='Минимальный элемент массива: '+IntToStr(a[min]) +#13+

'Номер элемента:'+ IntToStr(min);

end;    

 

На рисунке 5.3 приведен вид диалогового окна приложения после щелчка на кнопке Пуск.

 

   

 

Рисунок 5.3 - Окно приложения Поиск минимального элемента массива

 

5.2.4 Поиск в массиве заданного элемента

 

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

         Для организации поиска в массиве могут быть использованы различные алгоритмы. Наиболее простой — это алгоритм простого перебора. Поиск осуществляется последовательным сравнением элементов массива с образцом до тех пор, пока не будет найден элемент, равный образцу, или не будут проверены все элементы. Алгоритм простого перебора применяется, если элементы массива не упорядочены. Ниже приведен текст программы поиска в массиве целых чисел. Перебор элементов массива осуществляется инструкцией repeat, в теле которой инструкция if сравнивает текущий элемент массива с образцом и присваивает переменной found значение true, если текущий элемент и образец равны.

         Цикл завершается,  если в массиве обнаружен элемент, равный образцу (в этом случае значение переменной found равно true), или если проверены все элементы массива. По завершении цикла по значению переменной found можно определить, успешен поиск или нет. Вид диалогового окна программы Поиск в массиве приведен на рисунке 5.4.

Щелчок на командной кнопке Поиск (Buttonl) запускает процедуру TForm1.ButtonlСlick (ее текст приведен в листинге 5.4), которая из компонента StringGridl вводит массив, а из поля редактирования Edit2 — число (образец). Затем выполняется проверка, содержит ли массив введенное число. После завершения проверки процедура ShowMessage выводит сообщение о результате поиска. Код программы Поиск в массиве показан в листинге 5.4.

 

  

 

  

 

Рисунок 5.4 - Диалоговое окно программы Поиск в массиве

 

Листинг 5.4. Поиск в массиве

procedure TForm1.Button1Click(Sender: TObject);

const

                        SIZE=5;

var

                        a: array[1..SIZE] of integer; // массив

                        obr: integer; // образец для поиска

found: boolean; //TRUE -  совпадение образца  с //элементом массива

                        i: integer;        // индекс элемента массива

begin

                        // ввод массива

                        for i:=1 to SIZE do

                                   a[i] := StrToInt(StringGridl.Cells[i-l,0);

                                   // ввод образца для поиска

                        obr := StrToInt(edit2.text);

                        // поиск

            found := FALSE; // пусть нужного элемента нет

                        i := 1;

                        repeat

                                   if a[i] = obr

                                               then found := TRUE

                                   else i := i+1;

                        until (i > SIZE) or (found = TRUE);

                        if found

                                   then ShowMessage('Совпадение с элементом номер '

                                   +IntToStr(i)+#13+'Пoиск успешен.')

                        else ShowMessage('Совпадений с образцом нет.');

end;

 

5.2.5 Сортировка массива

Под сортировкой массива подразумевается процесс перестановки элементов массива, целью которого является размещение элементов массива в определенном порядке. Например, если имеется массив целых чисел а, то после выполнения сортировки по возрастанию должно выполняться условие:

а[1]   <= а[2]   <=  ... <= a[SIZE]

где SIZE — верхняя граница индекса массива.

         Существует много методов (алгоритмов) сортировки массивов. Рассмотрим один из них - метод прямого выбора.

Алгоритм сортировки массива по возрастанию методом прямого выбора может быть представлен так:

1)     Просматривая массив от первого элемента, найти минимальный элемент и поместить его на место первого элемента, а первый — на место минимального.

2)     Просматривая массив от второго элемента, найти минимальный элемент и поместить его на место второго элемента, а второй — на место минимального.

3)     И так далее до предпоследнего элемента.

Ниже представлена программа сортировки массива целых чисел по возрастанию, диалоговое окно которой изображено на рисунке 5.5.

 

 

Рисунок 5.5 - Диалоговое окно программы Сортировка массива простым выбором

 

Процедура сортировки, текст которой приведен в листинге 5.5 запускается нажатием кнопки Сортировка (Button1). Значения элементов массива вводятся из ячеек компонента StringGridl. После выполнения очередного цикла поиска минимального элемента в части массива процедура выводит массив в поле метки (Label2).

 

 

 

Листинг 5.5. Сортировка массива простым выбором

procedure TForm1.Button1Click(Sender: TObject);

const

                        SIZE=10;

var

                        a: array[1..SIZE] of integer;

                        min:integer; // номер минимального элемента массива

                                                           // от  1 до верхней границы массива

                               j:integer; //номер элемента, сравниваемого минимальным

buf: integer; // буфер, используемый при обмене //элементов массива

                        i,k: integer;

begin

                        // ввод массива

                        for i:=1 to SIZE do

                                   a[i]:=StrToInt(StringGrid1.Cells[i-1,0]);

                        label2.caption:= '';

                        for i:=1 to SIZE-1 do

                        begin

                                   { поиск минимального элемента в части массива

                                   от а[1] до a[SIZE]}

                                   min:=i;

                                   for j:=i+1 to SIZE do

                                               if  a[j] < a[min] then min:=j;

                                               //поменяем местами a [min] и a[i]

                        buf:=a[i];

                        a[i]:=a[min];

                        a[min]:=buf;

                                   // вывод массива 

                                   for k:=1 to SIZE do

                                   Label2.caption:=label2.caption+''+IntTostr(a[k]);

                                   Label2.caption:=label2.caption+#13;

                        end;

                        Label2.caption:=label2.caption+#13+'Maccив отсортирован.';

end;

 

5.3 Задания

 

1)       С помощью массива и цикла for выведите в компоненте Label сумму чисел от 1 до 10.

2)       С помощью массива и цикла while выведите в компоненте Label дату вашего рождения: 1 ячейка массива = 1 цифра.

3) С помощью трех массивов и цикла Repeat вывести ваши ФИО. После чего перезаписать числа в обратном порядке в те же массивы.

         Лабораторная работа 6. Подпрограммы.

        

Цели работы:

– научить создавать и использовать процедуры и функции;

- научить создавать и использовать модули.

        

6.1. Концепция модульного программирования

                  

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

        

         6.2. Виды подпрограмм.

 

         В Pascal есть два вида подпрограмм: процедуры и функции. Рассмотрим процедуру вычисления квадратного корня числа, приведенную в листинге 6.1.

 

Листинг 6.1 // Процедура вычисления квадратного корня числа

1          procedure TForm1.Button1Click(Sender: TObject);

2          var

3                      value: real;

4                      result: string;

5          begin

6                      value:= StrToFloat(edit1.Text);

7                      value:= sqrt(value);

8                      result:=FloatToStr(value);

9                      Memo1.Lines.Add('Квадратный корень числа '

10                                           + edit1.Text + ' равен ' + result);

11        end;

           

         Номера строк не являются частью исходного кода, они введены здесь только для того, чтобы можно было сослаться на определенную строку. Пользовательский интерфейс этой программы состоит из формы и четырех компонентов на форме Form1: надписи Label1 , поля ввода Edit1, кнопки Button1 и области просмотра Memo1 (Рисунок 6.1).

 

 

        

Рисунок 6.1 – Процедура вычисления квадратного корня числа

В приведенном выше коде строка 1 является объявлением процедуры — обработчика компонента Button1. Из кода видно, что это обработчик, а не обычная процедура, потому что в объявлении присутствует (Sender: TObject). Это выражение указывает на то, что процедура активизируется событием, происходящим с объектом Sender типа TObject (базовый класс в Delphi). Все обработчики событий Delphi являются процедурами.

         Рассматриваемый обработчик содержит вызовы функций. В строке 6 вызывается функция StrToFloat(), в строке 7 вызывается встроенная арифметическая функция Sqrt(), вычисляющая квадратный корень числа, а в строке 8 — функция FloatToStr().

         И наконец, в строках 9—10 вызывается метод Add() свойства Lines, принадлежащего объекту - области просмотра Memo1. Вызов метода Add() добавляет в область просмотра новую строку. Метод — это процедура или функция, ассоциированная с классом объектов, причем класс является типом объекта. Обычно методы предназначены для изменения одного или нескольких свойств объектов. В данном случае метод Add() изменяет свойство Lines (которое, в свою очередь, тоже является объектом).

 

6.3. Фактические и формальные параметры

 

         Для процедур и функций общим является наличие списка параметров, приводимого в скобках после имени процедуры, или функции.

         Рассмотрим следующий пример. Процедура Adder () вычисляет сумму двух вещественных чисел numl и num2:

 

{Суммирование переменных numl  и num2  и сохранение результата в переменной sum}

 

procedure Adder(numl Real; num2: Real; var sum: Real);

begin

            sum := numl + num2;

end;

 

         В этом коде переменные numl, num2 и sum являются формальными параметрами процедуры Adder(). При вызове подпрограммы формальным параметрам присваиваются значения фактических параметров. Таким образом в вызываемую подпрограмму передается информация из вызывающей подпрограммы.

         Список формальных параметров, заданный в объявлении процедуры Adder() состоит из трех элементов. Это информирует компилятор о том, что в процедуру Adder() при вызове будут переданы три вещественных числа.

         Ниже приведена простая тестовая программа для процедуры Adder ().

 

{Суммирование двух введенных пользователем чисел}

procedure Adder(num1:real; num2:real; var sum:real);

begin

sum := num1 + num2;

end;

 

procedure TForm2.Button1Click(Sender: TObject);

var

            firstNum: Real;

            secondNum: Real;

            result: Real;

begin

            firstNum :=StrToFloat(Edit1.Text);

secondNum :=StrToFloat(Edit2.Text);

Adder(firstNum,   secondNum,   result);

Label1.Caption := FloatToStr(result);

 

end;

        

Переменные firstNum, secondNum и result являются фактическими параметрами процедуры Adder(), они содержат значения, передаваемые в процедуру. Фактическим параметром может быть любое выражение, имеющее тот же тип, что и соответствующий ему формальный параметр.

         При составлении списка формальных параметров необходимо учитывать следующее.

1)     Количество формальных параметров должно быть равно количеству фактических параметров.

2)     Первый формальный параметр в списке соответствует первому фактическому, второй — второму и т.д.

3)     Тип каждого фактического параметра должен совпадать с типом соответствующего ему формального параметра.

4)     Имя фактического параметра никак не связано с именем соответствующего формального параметра.

5)     Необходимо строго различать способы передачи данных — по ссылке, или по значению.

 

6.4. Определение и использование подпрограмм

 

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

 

            procedure имя_процедуры (формальный_параметр1:.  тun1;

                                                           формальный_параметр2:  тип2;   . . .) ;

                        [локальные_объявления; ]

            begin

                        [операторы; ]

            end;

 

                Чтобы вызвать процедуру, нужно задать ее имя и список фактических параметров. Синтаксис вызова процедуры имеет вид

 

имя_процедуры (фактический_параметр ,фактический_параметр2,…);

 

         Функции несколько отличаются от процедур. В функцию можно передавать любое количество параметров, однако она всегда возвращает одно значение в вызывающую подпрограмму. В то же время процедура не обязательно должна что-либо возвращать. Если в вызывающую подпрограмму необходимо возвращать одно значение, то рекомендуется использовать функцию. Изменим процедуру Adder() на функцию.

 

{Функция Adder() возвращает сумму переменных num1 и num2}         

 

function Adder(numl Real; num2: Real):Real;

begin

            Adder  := numl  +  num2;

end;

 

Тестовая программа для функции имеет следующий вид:

 

procedure TForm2.Button1Click(Sender: TObject);

 

var

            firstNum: Real;

            secondNum: Real;

            result: Real;

begin  

            firstNum :=StrToFloat(Edit1.Text);

            secondNum :=StrToFloat(Edit2.Text);

            result := Adder(firstNum,   secondNum);

Label1.Caption := FloatToStr(result);

end;

 

         Синтаксис определения пользовательской функции имеет следующий вид:

        

function имя_ функции {формальный_параметр1: mun1; ...): тип_функции ;

            [локальные объявления: ]

            begin

                        [операторы; ]

                        имя_функции  := возвращаемое_значение;

            end;

 

         Обратите внимание: функция определяется с заданным типом тип_функции. Этот тип имеет значение, возвращаемое из функции в вызывающую процедуру. Чтобы вернуть в вызывающую процедуру возвращаемое_значение, оно должно быть присвоено имени имя_функции в любом месте внутри блока функции (между ключевыми словами begin и end).

 

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

 

            имя_переменной := имя_функции (фактический параметр 1,

                                                                       фактический_параметр2,   . . .) ;

 

         Чтобы функцию Adder() можно было вызвать из другого модуля, в интерфейсном разделе модуля, в котором она определена, должен быть приведен ее заголовок:

         interface

           

            uses

                        Windows, Messages, SysUtils, Classes, Graphics,                                          Controls, Forms, Dialogs, StdCtrls;

                                   .

                                   .

                                   .

            function Adder(numl: Real; num2: Real): Real;

                                   .

                                   .

                                   .

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

 

 

Рис.6.2. Суммирование двух введенных пользователем чисел

           

Листинг 6.2 // Суммирование двух введенных чисел

unit UAdderFunc;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

type

TForm2 = class(TForm)

Edit1: TEdit;

Edit2: TEdit;

Edit3: TEdit;

Label1: TLabel;

Label2: TLabel;

Button1: TButton;

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form2: TForm2;

function Adder(num1:real; num2 :real) : real;

implementation

{$R *.dfm}

{Суммирование двух чисел, введенных пользователем}

procedure TForm2.Button1Click(Sender: TObject);

var

            firstNum: Real;

            secondNum: Real;

            result: Real;

            code: Integer;

begin

firstNum:= StrToFloat(Edit1.Text);

secondNum:= StrToFloat(Edit2.Text);

result := Adder(firstNum, secondNum);

Edit3.Text :=FloatToStr(result);

end;

 

{Функция возвращает суму чисел numl и num2}

function Adder(num1: Real; num2: Real): Real;

begin

            Adder := num1 + num2;

end;

end.

        

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

         В листинге 6.3 приведен код фрагмента программы вычисления квадратного корня числа, в которой используется функция SqRoot.

        

Листинг 6.3 // Вычисление квадратного корня числа с //использованием функции SqRoot

var

Form1: TForm1;

implementation

{$R *.dfm}

function SqRoot(value: real): real;

begin

result := sqrt(value);

end;

procedure TForm1.Button1Click(Sender: TObject);

var

value: real;

begin

value := SqRoot(StrToFloat(edit1.Text));

memo1.Clear;

memo1.Lines.Add('Квадратный корень числа ' + edit1.Text + ' равен ' + FloatToStr(value));

end;

end.

 

         6.5 Передача параметров

 

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

Передача по значению - это передача в подпрограмму значения фактического параметра, т.e. копии объекта. При этом подпрограмма работает не с объектом, а с его копией. Передача по значению предохраняет объект от изменения подпрограммой. По умолчанию в Pascal параметры передаются по значению.

 

         Параметры можно передавать в подпрограмму по ссылке или по значению. При передаче по ссылке в подпрограмму передается только информация о расположении переменной в памяти. Это позволяет подпрограмме получить доступ непосредственно к самой переменной. Следовательно, подпрограмма может изменить значение переменной.

         В то же время при передаче по значению в подпрограмму передается значение переменной, т.е. подпрограмма получает доступ только к копии переменной. Изменить значение самой переменной подпрограмма не может. В Delphi по умолчанию параметры передаются по значению. Рассмотрим пример, иллюстрирующий передачу параметра по значению. Текст соответствующей программы приведен в листинге 6.4, а результат ее выполнения – на рисунке 6.3.

        

Листинг 6.4 Пример передачи параметра по значению

{Передача  в процедуру MyProcedure  параметра по  значению}

procedure MyProcedure(number: Integer);

begin

            Form2.Memo1.Lines.Add('Начало работы   MyProcedure: ' +

' number = ' +  IntToStr(number));

            number := 2 * number;

Form2.Memo1.Lines.Add('Завершение работы MyProcedure : ' + ' number = ' + IntToStr(number));

end;

 

{Тестовая программа для MyProcedure}

procedure TForm2.Button1Click(Sender: TObject);

var

            value: Integer;

begin

            value := 5 ;

            Memo1.Clear;

Memo1.Lines.Add('Начало работы тестовой программы:   value = ' + IntToStr(value));

            MyProcedure(value);

Memo1.Lines.Add('Завершение работы тестовой программы: value = ' + IntToStr(value));

end;

 

 

Рисунок 6.3 - Передача параметра по значению

        

В этом фрагменте кода параметр number передается по значению.

         Обратите внимание: значение переменной value не затронуто операциями, выполненными в процедуре MyProcedure.

         Модифицируем этот пример. Добавим перед объявлением переменной number ключевое слово var, означающее, что параметр number передается по ссылке.

         Новый вариант кода (листинг 6.5) почти идентичен предыдущему.

 

Листинг 6.5. Пример передачи параметра по ссылке

procedure MyProcedure(var number: Integer);

begin

            Form2.Memo1.Lines.Add('Начало работы   MyProcedure: ' +

' number = ' +  IntToStr(number));

            number := 2 * number;

            Form2.memO1.Lines.Add('Завершение работы MyProcedure : ' +

' number = ' + IntToStr(number));

end;

 

{Тестовая программа для MyProcedure}

procedure TForm2.Button1Click(Sender: TObject);

var

            value: Integer;

begin

            value := 5 ;

            Memo1.Clear;

Memo1.Lines.Add('Начало работы тестовой программы: value = ' + IntToStr(value));

            MyProcedure(value);

Memo1.Lines.Add('Завершение работы тестовой программы: value = ' + IntToStr(value));

end;

 

 

Рис.6.4 – Пример передачи параметра по ссылке

        

В этом примере параметр number передается по ссылке.

         Поскольку параметр number фактически является переменной value, процедура MyProcedure изменила значение value.

 

6.6. Повторное использование функций и процедур

 

         Чтобы подпрограмма была доступна в других модулях, копия заголовка подпрограммы должна быть записана в интерфейсном разделе модуля, в котором подпрограмма определяется. Тогда подпрограмма будет иметь публичную область видимости. Это означает, что она может быть использована в любом модуле, в интерфейсном разделе которого после ключевого слова uses указано имя модуля, содержащего определение подпрограммы. Обычно все заголовки пользовательских подпрограмм в интерфейсном разделе располагаются последовательно один за другим.

         Таким образом, интерфейсный раздел модуля должен содержать заголовки всех публичных пользовательских подпрограмм, которые будут вызываться в других модулях.

         Если подпрограмма определена в модуле и вызывается в разделе реализации, но заголовок подпрограммы в интерфейсном разделе не приведен, то она называется приватной подпрограммой. Приватную подпрограмму можно вызывать только в том модуле, в котором она определена.

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

         6.7 Создание модуля

 

Delphi позволяет программисту поместить свои функции и процедуры в отдельный модуль, а затем использовать процедуры и функции модуля в своих программах, указав имя модуля в списке модулей, необходимых программе (инструкция uses).

         Чтобы приступить к созданию модуля, нужно сначала закрыть окно формы и окно модуля формы (в ответ на вопрос о необходимости сохранения модуля следует выбрать No, т. е. модуль, соответствующий закрытой форме сохранять не надо). Затем из меню File нужно выбрать команду New | Unit. В результате открывается окно редактора кода, в котором находится сформированный Delphi шаблон модуля (Рисунок 6.5).

 

 

Рисунок 6.5 - Шаблон модуля

 

Начинается модуль заголовком — инструкцией unit, в которой указано имя модуля. Во время сохранения модуля это имя будет автоматически заменено на имя, указанное программистом.

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

         В раздел implementation (реализация) нужно поместить процедуры и функции, объявленные в разделе interface.

         В качестве примера в листинге 6.6 приведен модуль программиста, который содержит рассмотренные ранее функцию FuntToKg и процедуру SqRoot.

 

Листинг 6.6. Модуль программиста

unit My_UnitEX;

interface

            // объявления процедур и функций, доступных

// программам, использующим этот модуль

            function FuntToKg(f:real):real;

            // Переводит вес из фунтов в килограммы

            procedure SqRoot(a,b,c: real; var x1,x2: real;

                         var ok: boolean);

            // решает квадратное уравнение

implementation // реализация

function FuntToKg(f:real):real;

            const

            // в России 1  фунт равен 409,5 гр.

            K=0.4095;   // коэф.   Пересчета

            begin

                        result:=f*K;

            end;

procedure SqRoot(a,b,c: real; var x1,x2: real;

                                                                       var ok: boolean);

            {  a,b,c — коэффициенты уравнения

            xl,x2 — корни уравнения

            ok = True    — решение есть

            ok = False — решения нет }

var

                        d : real;   // дискриминант

begin

                        d:=  Sqr(b) - 4*a*c;

                        if d <  0 then

                                   ok := False // уравнение не имеет решения

                        else begin

                                   ok := True ;

                                   x1 :=(-b +  Sqrt(d)) / (2*a);

                        x2 :=(b + Sqrt(d)) / (2*a) ;

                        end;

end;

end.

           

Сохраняется модуль обычным образом, т. е. выбором из меню File команды Save. Вместе с тем, для модулей повторно используемых процедур и функций лучше создать отдельную папку, назвав ее, например, Units.

 

6.8 Использование модуля

 

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

         После добавления имени модуля в список модулей, используемых приложением, сам модуль нужно добавить в проект. Для этого из меню Project надо выбрать команду Add to Project и в открывшемся диалоговом окне  — имя файла модуля. В результате добавления модуля к проекту в окне редактора появится вкладка с текстом добавленного к проекту модуля.

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

 

 

 

Рисунок 6.6. Окно программы Использование модуля

 

Листинг 6.7. Использование модуля программиста

unit UnitEx;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,My_UnitEx;

type

                        TForm2 = class(TForm)

                        Edit1: TEdit;

                        Edit2: TEdit;

                        Edit3: TEdit;

                        Edit4: TEdit;

                        Label1: TLabel;

                        Label2: TLabel;

                        Button1: TButton;

                        Button2: TButton;

                        procedure Button2Click(Sender: TObject);

                        procedure Button1Click(Sender: TObject);

private

                        { Private declarations }

public

                        { Public declarations }

end;

var

                        Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

var

                        kl,k2: real;  // корни уравнения

                        rez: boolean; // True —решение есть, False —решения нет

                        mes: string;  // сообщение

begin

                        a := StrToFloat(Edit1.Text);

                        b := StrToFloat(Edit2.Text);

                        c := StrToFloat(Edit3.Text);

                        SqRoot(a,b,c, k1,k2, rez); // вызов процедуры

                        if rez then

mes := 'Корни уравнения' + #13 +'x1='+FloatToStr(kl)+#13+ 'x2='+FloatToStr(k2)+#13

                        else

                                   mes := 'Уравнение не имеет решения';

                        label1.Caption := mes;

            end;

procedure TForm2.Button2Click(Sender: TObject);

var

                        funt:real;

                        kg:real;

begin

                        funt :=StrToFloat(Edit4.Text);

                        kg:=FuntToKg(funt);//Вызов функции

                        Label1.Caption :=  FloatToStr(kg);

            end;

end.

 

          6.9 Контрольные вопросы

 

1)     Что такое модульное программирование? Назовите два типа подпрограмм.

2)     Приведите синтаксис определения и вызовов процедуры и функции.

3)     В каких случаях использование функции предпочтительнее использования процедуры?

4)     Что такое передача параметров по ссылке и по значению? Каким образом в программе можно задать вид передачи параметров?

 

6.10 Задания

 

1)     Разработайте программу, которая приглашает пользователя ввести свое имя и фамилию в двух отдельных полях ввода, а затем в области просмотра выводит фамилию, запятую и имя (в этой последовательности). Выведите строку в области просмотра Memo1 с помощью подпрограммы.

2)     Разработайте программу, приглашающую пользователя ввести свое имя и фамилию в двух отдельных полях ввода и выводящую их буквами, переставленными в обратной последовательности. Инвертирование последовательности букв должно выполняться одной подпрограммой, а вывод результата — другой. Программа должна автоматически сделать первые буквы прописными. Например, Tom Smith должно быть выведено как Mot Htims.

3)  Разработайте программу, которая выводит в область просмотра Memo1 ваше имя, название курса, дату и название школы сразу после запуска (без ввода этих данных пользователем). Выводимые данные должны быть записаны в исходном коде, a не в свойстве Lines области просмотра во время разработки.

4)  Разработайте программу, выводящую в область просмотра сообщение “Ура! Наконец-то я обошелся без левой кнопки!”, когда пользователь щелкает правой кнопкой мыши в области просмотра.

 

Лабораторная работа 7 Ввод-вывод текстовых файлов

 

Цели работы:

- познакомить с операциями ввода и вывода текстовых файлов;

- научить создавать и обрабатывать текстовые файлы;

- познакомить с процедурами обработки текстовых файлов и управления файлами

 

Ввод файла - это операция чтения информации из файла.

Вывод файла - это операция записи информации в файл.

 

В Pascal поддерживаются три типа файлов данных: текстовые, типизированные и нетипизированные. В этой работе рассматриваются наиболее распространенные — текстовые файлы.

 

7.1 Текстовые файлы

 

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

Текстовый файл состоит из символов ASCII. Его можно создавать и редактировать с помощью любого текстового редактора, поддерживающего сохранение файлов в формате ASCII. В качестве примера создадим текстовый файл с помощью редактора кода Delphi. В главном меню Delphi выберите команду File=>New Other (Файл=>Новый...), при этом открывается диалоговое окно New Items (Новые элементы). Во вкладке New выделите пиктограмму Text, как показано на рисунке 7.1..

 

 

Рисунок 7.1 - Создание текстового файла с помощью редактора кода Delphi

 

Щелкните на кнопке ОК. При этом в окне редактора кода появляется пустая вкладка с именем по умолчанию Filel .txt (Рисунок 7.2).

Введите в этой вкладке следующие строки:

 

Anderson                    73

Castor             82

Hartley            91

McGuire                      89

Ramone                       67

Swanson                     78

 

В этих строках записаны фамилии студентов с их суммарными оценками. Сохраните файл. Для этого выберите команду File=>Save As... (Файл=>Сохранить как...), при этом появится диалоговое окно Save As. Введите имя файла examl.txt и в списке типов файла выберите Textfile (*.txt). Щелкнув на кнопке ОК, сохраните

examl .txt как текстовый файл ASCII.

 

7.2. Работа с текстовыми файлами

 

Чтобы получить доступ к файлу, его нужно открыть. По завершении всех необходимых операций с файлом его нужно закрыть.

Для получения доступа к текстовому файлу в Pascal нужно сначала объявить переменную типа TextFile, которая называется дескриптором файла. В дескрипторе хранится указатель файла, который похож на курсор в текстовом редакторе. Как и курсор, указатель файла обозначает текущую позицию в открытом текстовом файле. В режиме ввода указатель файла определяет следующий элемент данных, который будет считан из файла. В случае текстового файла таким элементом данных является символ. В режиме вывода указатель файла определяет позицию, в которую будет записан следующий элемент данных.

Объявив дескриптор файла, нужно связать его с файлом данных с помощью процедуры AssignFile(), синтаксис которой имеет вид

 

AssignFile (дескриптор_файла, имя_файла) ;

 

Строковое выражение имя_файла должно содержать любое правильное имя файла Windows. Если файл находится не в текущем каталоге, в выражении имя_файла должен быть указан его полный маршрут, включая имя диска и всех подкаталогов.

И наконец, для получения доступа к файлу его нужно открыть. Текстовый файл можно открыть или для ввода, или для вывода, но не для обоих операций одновременно. Процедура Reset() открывает или повторно открывает текстовый файл в режиме ввода, а процедуры Rewrite() и Append() открывают или повторно открывают текстовый файл в режиме вывода. Синтаксис этих процедур имеет вид

 

 

Reset (дескриптор_файла) ;

Rewrite (дескриптор_файла) ;

Append (дескриптор_файла) ;

 

Процедура Reset() открывает существующий файл данных, ассоциированный с заданным дескриптором, и устанавливает указатель файла в его начало. Если файл уже открыт, то сначала он закрывается, а затем открывается повторно. Если файла данных с указанным именем не существует, то генерируется ошибка file not found (файл не найден).

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

Для добавления данных в конец файла используется процедура Append(). Она открывает существующий файл, имя которого ассоциировано с дескриптором, и устанавливает указатель файла в конец файла. Если файл уже открыт, то процедура Append() закрывает его, а затем открывает повторно. Если файла с этим именем не существует, то генерируется ошибка file not  found.

Когда текстовый файл открыт в режиме чтения, из него можно читать данные с помощью процедуры Read(), синтаксис которой имеет вид

 

Read (дескриптор_файла, переменная) ;

 

Процедура Read() выполняет следующие операции.

1)                 Считывает из файла, ассоциированного с дескриптором, порцию данных, на которую показывает указатель файла.

2)                 Сохраняет считанные данные в переменной.

3)                 Передвигает указатель файла на следующую порцию данных.

 

Если с помощью процедуры Rewrite() или Append() файл открыт в режиме вывода, то в него можно записывать данные с помощью процедуры Write(), общий синтаксис которой имеет вид

 

Write (дескриптор_файла [, выражение [: минимальная_ширина

[: длина_дробной_части] ] ] ) ;

 

Выражение может иметь любой числовой или строковый тип, а минимальная_ширина и длина_дробной_части должны иметь целочисленный тип. Необязательный параметр минимальная ширина задает количество символов текстового файла, отводимых для выводимого выражения. Если длина выводимого выражения меньше указанной, то процедура Write() дополняет его пробелами слева, а если больше, то в файл выводится больше символов, чем задано выражением минимальная_ширина, т.е. выводятся все необходимые символы. Если выводится число вещественного типа, то необязательный параметр длина_дробной_части задает количество цифр после десятичной точки. Одним вызовом процедуры Write() в файл можно вывести произвольное количество выражений (включая нулевое). Выводимые выражения отделяются друг от друга запятыми. Например, оператор

 

Write(myFile, 10:5, 10.47589:8:2);

 

выводит в текстовый файл, ассоциированный с дескриптором myFi1е, следующий текст:

 

10       10.48

 

Когда программа закончила работу с файлом, его необходимо закрыть. Процедура CloseFile() разрывает связь дескриптора с файлом, возвращая эти ресурсы системе. Если файл был в режиме вывода, то процедура CloseFile() перед закрытием файла записывает в его конец символ конца файла <EOF>. Синтаксис процедуры CloseFile() имеет вид

 

CloseFile (дескриптор_файла);

 

7.3. Примеры работы с текстовыми файлами в графическом режиме

 

Пример 7.3.1.

Ниже приведен код модуля, в котором выполняется ввод и вывод в текстовый файл. В модуле используется файл examl.txt, создание которого описано выше в этой работе. Предполагается, что файл examl. txt находится в корневом каталоге диска с: \ (т.е. его маршрут имеет вид C:\examl.txt). В коде модуля создается текстовый файл names.txt тоже в корневом каталоге диска С:\. Программа записывает в файл names .txt все фамилии студентов из файла examl. txt. На рисунке 7.2 показана форма программы после выполнения кода модуля и содержимое файла names.txt.

 

Листинг 7.3.1.

{Чтение текстового файла examl.txt, вывод прочитанных данных

в область просмотра Memo1, создание файла names.txt

и запись в него фамилий студентов}

procedure TForm1.Button1Click(Sender: TObject);

var

inFile: TextFile;

outFile: TextFile;

lastName: String[10];

examScore: Integer;

begin

AssignFile(inFile, 'c:\exam1.txt');

AssignFile(outFile, 'с:\names.txt');

Reset(inFile);

Rewrite(outFile);

Writeln(outFile, 'Фамилия');

Writeln(outFile, ' ');

Memo1.Clear;

Memo1.Lines.Add('Студент  Экзамен 1');

Memo1 .Lines .Add( '  ' ) ;

while not(eof(inFile)) do begin

Readln(inFile, lastName, examScore);

Writeln(outFile, Trim(lastName));

Memo1.Lines.Add(lastName + IntToStr(examScore));

end;

Memo1. Lines. Add ('');

Memo1.Lines.Add('Создан файл С:\names.txt');

Memo1.Lines.Add('ПРОГРАММА ЗАВЕРШЕНА');

CloseFile(inFile);

CloseFile(outFile);

end;

 

        

Рисунок. 7.2 - Форма программы, демонстрирующей ввод-вывод в текстовые файлы и содержимое файла names.txt

 

Пример 7.3.2. Запись или добавление в текстовый файл.

 

На рисунке 7.3  приведено диалоговое окно программы, которая выполняет запись или добавление в текстовый файл.

 

Рисунок 7.3 - Диалоговое окно программы записи-добавления в файл

B листинге 7.3.2 приведена процедура, которая запускается нажатием командной кнопки Записать. Она открывает файл в режиме создания нового или замещения существующего файла и записывает текст, находящийся в поле компонента Memo1.

Имя файла нужно ввести во время работы в поле Edit1. Можно задать предопределенное имя файла во время разработки формы приложения. Для этого надо присвоить значение, например test.txt, свойству Edit1.Text.

 

Листинг 7.3.2 Создание нового или замещение существующего файла

procedure TForml.ButtonlClick(Sender: TObject);

var

            f: TextFile;      // файл

            fName: String[80]; // имя файла

            i:integer;

begin

            fName := Editl.Text;

            AssignFile(f, fName);

            Rewrite(f);  // открыть для перезаписи

            // запись в файл

            for i:=0 to Memol.Lines.Count do // строки нумеруются с нуля                  writeln(f, Memol.Lines[i]);

            CloseFile(f); // закрыть файл

            ShowMessage('Данные ЗАПИСАНЫ в файл ');

end;

 

В листинге 7.3.3 приведена процедура, которая запускается нажатием командной кнопки Добавить. Она открывает файл, имя которого указано в поле Edit1, и добавляет в него содержимое поля Memol.


 

Листинг 7.3.3 Добавление в существующий файл

procedure TForml.Button2Click(Sender: TObject);

var

f: TextFile;      // файл

fName: String[80]; // имя файла

i: integer;

begin

fName := Editl.Text;

AssignFile(f, fName);

Append(f);  // открыть для добавления

            // запись в файл

            for i: =0 to Memol.Lines.Count do

                       writeln(f,   Memol.Lines[i]);

            CloseFile(f);   // закрыть файл

            ShowMessage('Данные ДОБАВЛЕНЫ в файл ');

end;

 

 

7.4 Контрольные вопросы

 

1)      Для чего используются файлы данных?

2)      Назовите три типа файлов данных в Pascal.

3)      Что такое последовательный файл? Как его создать?

4)       Напишите код, выполняющий над текстовым файлом MyData.txt следующие операции:

а)      открытие файла в режиме ввода;

б)      открытие файла в режиме вывода (с уничтожением старых данных);

в)      открытие файла в режиме вывода (без уничтожения старых данных).

 

7.5 Задания

 

1)     Создайте программу, выводящую содержимое текстового файла в область просмотра (строка за строкой). Программа должна только скопировать данные файла на экран.

2)     Создайте программу, записывающую в текстовый файл 10 чисел, введенных пользователем.

3)     Создайте программу, читающую из текстового файла 10 чисел и выводящую эти числа с их суммой в область просмотра.

4)     Создайте программу, читающую 10 чисел из текстового файла и выводящую эти числа с их суммой в другой текстовый файл в формате отчета.

5)     Создайте программу, выводящую ваши имя и дату рождения в текстовый файл.

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

7)     Создайте программу, выводящую ваши имя и дату рождения в текстовый файл в формате отчета.

8)      

Список литературы

 

1) А.Я. Архангельский. Язык Pascal и основы программирования в Delphi. Учебное пособие. – М.: Бином, 2004. - 496 с.

2) С.Бобровский. Технологии Delphi. Разработка приложений для бизнеса. Учебный курс. – СПб.:Питер, 2007. – 720 с.

3) Н.Культин. Основы программирования в Delphi 7. Самоучитель. – СПб.: БХВ-Петербург, 2005. – 598 с.

4) Митчелл К. Керман. Программирование и отладка в Delphi. Учебный курс.- М., СПб., Киев. 2004. – 712 с.

5) И. Хладни. Внутренний мир Borland Delphi 2006. - М., СПб., Киев. 2006. - 764 с.

6) В.В. Фаронов. Программирование на языке высокого уровня Delphi. Учебное пособие. – Питер, 2004, - 640 с.

7) М.Е. Фленов. Библия Delphi. 2-е изд, СПб.: БХВ-Петербург, 2009. –

    800 с.

  

Содержание

Введение                                                                                                  3

Лабораторная работа 1. Знакомство с ИСР Delphi                                 4

Лабораторная работа 2. Создание приложений с использованием

     функций и компонентов ввода/вывода данных                                 14

Лабораторная работа 3. Структуры выбора                                           22

Лабораторная работа 4. Циклические структуры                                  31

Лабораторная работа 5. Операции с массивами                                              38

Лабораторная работа 6. Подпрограммы                                                47

Лабораторная работа 7. Ввод-вывод текстовых файлов                        60

Список литературы                                                                                 67