close

Вход

Забыли?

вход по аккаунту

?

564.Сазонова С.А. Компьютерные технологии- лабораторный практикум

код для вставкиСкачать
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ
Федеральное государственное бюджетное образовательное учреждение
высшего профессионального образования
«ВОРОНЕЖСКИЙ ГОСУДАРСТВЕННЫЙ АРХИТЕКТУРНОСТРОИТЕЛЬНЫЙ УНИВЕРСИТЕТ»
КОМПЬЮТЕРНЫЕ ТЕХНОЛОГИИ
Лабораторный практикум
Составители:
С. А. САЗОНОВА
С. А. КОЛОДЯЖНЫЙ
Е. А. СУШКО
Воронеж 2015
1
УДК 614.841:004(07)
ББК 38.96:32.973-018я73
К 637
Рецензенты:
кафедра пожарной безопасности технологических процессов
Воронежского института ГПС МЧС России;
А.В. Некрасов, к. т. н., доцент кафедры пожарной безопасности
технологических процессов Воронежского института ГПС МЧС России
КОМПЬЮТЕРНЫЕ ТЕХНОЛОГИИ: лабораторный практикум /
К 637 сост. С.А. Сазонова, С.А. Колодяжный, Е.А. Сушко; Воронежский
ГАСУ. – Воронеж, 2015. – 143 с.
ISBN 978-5-89040-548-7
Содержит методические материалы к выполнению лабораторных работ по
курсу «Компьютерные технологии». Работы включают теоретическую часть,
примеры решения задач, рекомендации по выполнению заданий, контрольные
вопросы по изучаемой теме, задания для лабораторных работ. Творческий подход студентов к выполнению работ обеспечивается использованием в каждой
лабораторной работе большого количества вариантов индивидуальных заданий.
Предназначен для студентов, обучающихся по специальности 20.05.01 «Пожарная безопасность», и по направлению 20.03.01 «Техносферная безопасность».
Ил. 40. Табл. 15. Библиогр.: 56 назв.
Печатается по решению учебно-методического совета
Воронежского ГАСУ
ISBN 978-5-89040-548-7
УДК 614.841:004(07)
ББК 38.96:32.973-018я73
© Сазонова С. А., Колодяжный С. А.,
Сушко Е. А., составление, 2015
© Воронежский ГАСУ, 2015
2
ВВЕДЕНИЕ
Одним из решающих факторов ускорения научно-технического прогресса
на современном этапе является широкое использование средств вычислительной техники во всех областях человеческой деятельности.
Это обстоятельство диктует необходимость подготовки специалистов, сочетающих знание своей специальности с навыками использования современных
персональных компьютеров (ПК) для решения разнообразных инженерных задач.
Учебное пособие составлено в соответствии с требованиями государственного образовательного стандарта высшего профессионального о бразования по специальности 20.05.01 «Пожарная безопасность» и по направлению
20.03.01 «Техносферная безопасность», предназначено для использования студентами в качестве руководящего материала при прохождении лабораторного
практикума по курсу «Компьютерные технологии».
Пособие содержит вводный раздел, посвященный общим правилам выполнения лабораторных работ, в том числе правилам решения задач, и лабораторные работы. Лабораторные работы включают краткое изложение теоретического
материала, примеры решения задач, рекомендации для выполнения заданий, задания для лабораторных работ и контрольные вопросы по изучаемой теме.
Теоретический материал, примеры алгоритмов и программ и рекомендации
по лабораторным работам студенты должны изучить самостоятельно.
Работы выполняются студентами по индивидуальным вариантам заданий,
выдаваемых преподавателем. На контрольные вопросы по теоретическому материалу, примерам алгоритмов и программ и рекомендациям по лабораторным
работам студент должен ответить перед проведением лабораторных работ.
В учебном пособии использованы авторские наработки, а также в учебных целях наработки из учебного пособия [1]. В библиографическом списке
указаны литература рекомендуемая литература для самостоятельного изучения
по курсу «Компьютерные технологии» и интернет-ресурсы (электоронные библиотеки) [2-7].
На основе полученных навыков программирования на языке высокого
уровня, в дальнейшем студент сможет самостоятельно решать технические задачи на компьютерах. Преобладающее число современных научных разработок
выполнено с применением вычислительной техники и программирования.
Примеры решения технических задач можно посмотреть в библиографическом
списке, в котором приведены учебные и научные наработки сотрудников кафедры пожарной и промышленной безопасности Воронежского государственного инженерно-строительного университета [8-56]. Изучение и использование
указанных наработок в учебном процессе будет способствовать повышению
уровня знаний студентов по дисциплинам выпускающей кафедры "Пожарная и
промышленная безопасность".
3
1. ОСНОВНЫЕ ПОНЯТИЯ ЯЗЫКА С/С++ BUILDER
1.1. C++ Builder – система визуального
объектно-ориентированного программирования
В настоящее время язык С/С++ является одним из наиболее распростр аненных и востребованных языков программирования. Этот язык представляет
собой фундамент, на котором строится современное программирование и может быть использован для решения технических задач [1].
Лабораторные работы могут выполняться студентами с использованием
любого из доступных им компиляторов. Наиболее удобным для первоначального изучения языка С является интегрированная среда программирования
Borland С версий 3.0/3.1. Хотя эти версии не позволяют создавать современные 32-разрядные приложения, они обладают другими более важными для
студентов качествами:
интерфейс сред ВС 3.0/3.1 унифицирован со средой Turbo Pascal 7.0, которая, как правило, уже знакома студентам к моменту начала изучения языка С,
поэтому они могут не отвлекаться на изучение новой среды;
среды ВС 3.0/3.1 предоставляют пользователям удобную справочную
систему, а также эффективные средства поиска ошибок и отладки программ;
в отличие от многих других версий указанные версии устойчиво поддерживают русский язык, что позволяет легко комментировать разрабатываемые программы (это особенно важно на начальном этапе изучения языка).
Как показывает практика, овладев одной из этих сред, студенты легко
переходят к более современным системам, включая среду визуального программирования C++ Builder.
Разрабатывая программу, студент ориентируется на ту или иную среду
разработки, компилятор. Программировать на C++ можно как в среде Windows,
так и в DOS, причем для каждой из операционных систем существует довольно
большое количество средств разработки: от компилятора, работающего в р ежиме командной строки DOS, до мощной интерактивной среды разработки.
Если вы только осваиваете язык программирования, то следует сосредоточиться именно на языке, его возможностях, особенностях работы в DOS, в среде
разработки Воrland C++ Version 3.1, которая, безусловно, может быть запущена и
из Windows. Следует особо обратить внимание на то, что хотя Borland C++ и был
создан довольно давно, это профессиональная, высокоэффективная среда разр аботки, которая наилучшим образом подходит для изучения языка программир ования высокого уровня C++.
C++ Builder – одна из самых мощных систем визуального объектноориентированного программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром
определенного типа (класса). Программа, построенная по принципу объектной
ориентации – это не последовательность операторов, реализующих некий жест4
кий алгоритм, а совокупность объектов и способов их взаимодействия. Объект
– это совокупность свойств и методов, а также событий, на которые он может
реагировать [2].
Внешнее управление объектами осуществляется через обработку событий, порождаемых пользователем путем воздействия на объекты интерфейса,
например, при щелчке мышью по командной кнопке. Эти обработчики событий, называемые функциями обработки событий, обращаются к методам и
свойствам объекта и выполняют определенные в программе действия (проведение вычислений, вызов функций, создание графических изображений и т. д.). В
результате выполнения этих действий объект может изменить собственное с остояние и сформировать сообщения другим объектам. Таким образом, процессом решения задачи управляет последовательность событий и сообщений.
Создание объектов и написание программ функций обработчиков событий является важнейшей частью разработки графического интерфейса польз ователя. Важнейшее значение при объектно-ориентированном программировании имеют принципы инкапсуляции, сущность которой заключается в том, что
внешним объектам и пользователям прямой доступ к кодам объекта запрещен.
Для пользователей программным продуктом доступ к методам и свойствам
объектов и данным доступен только через пользовательский интерфейс в объеме, предусмотренном проектировщиком программного продукта.
Программирование вручную графического интерфейса программы (разработка привычных пользователю окон для ввода и отображения информации,
кнопок, меню, обработка событий мыши и клавиатуры, включение в программы изображений и звука) требует больших затрат времени программиста. Выход из этой ситуации обозначился благодаря двум подходам. Первый – стандартизация системных функций и появление пользовательских интерфейсов
API. В них описаны функции, переменные, константы, к которым разработчик
может обратиться при разработке программы. Второй – это появление визуального программирования, возникшего в Visual Basic и нашедшего воплощение в
C++ Builder. Это позволило свести разработку графического пользовательского
интерфейса к простым и наглядным процедурам размещения имеющихся в
классов объектов (компонентов) из библиотеки C++ Builder на оконной форме.
Основное достоинство визуального проектирования заключается в том,
что во время проектирования формы и размещения на ней компонентов
C++ Builder автоматически формирует коды программы, включая в нее соответствующие фрагменты, описывающие свойства компонент. Программы в
С++ Builder разрабатываются под Windows. Для написании кода программы в
C++ Builder используется язык С++, дополненный новыми классами, типами
переменных и функций. Поэтому, в связи с ограниченным объемом пособия,
оно ориентировано на студентов, знакомых с семантикой и синтаксисом языка
C++.
5
1.2. Общие сведения о программах на C++ Builder
Программа на C++ Builder состоит из объявлений переменных, констант,
типов, классов, функций и описания функций [1]. Среди функций всегда имеется главная WinMain, Программа начинает работать именно с этой главной
функции. Программа строится по модульному принципу и состоит из множества модулей. Все объекты компонентов размещаются на объектах – формах;
для каждой формы создается отдельный модуль. Именно в модулях и размещается программа.
В обработчиках событий объектов – форм и компонентов пишутся коды
программы. В процессе проектирования приложения C++ Builder автоматически создает коды головного файла, имеющего расширение (.cpp) и содержащего главную функцию проекта WinMain, коды заголовочных файлов интерфейса
отдельных модулей и коды их файлов реализации. Чтобы увидеть код головного файла проекта надо в среде разработки С++ Builder в меню Project выбрать
команду View Sourse. Типичный файл проекта имеет следующий вид:
Головной файл проекта:
//--------------------------------------------------------------------------// директивы препроцессора
#include <vcl.h>
#pragma hdrstop
//--------------------------------------------------------------------------//макросы, подключающие файлы ресурсов и форм
USEFORM("UnGraf1.cpp", Form1);
//--------------------------------------------------------------------------//главная функция WinMain
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{ //тело главной функции, инициализирующее объекты компонентов
данного приложения
Application->Initialize();
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run(); //начало выполнения программы
}//обработка исключений(аварийных ситуаций)
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
6
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0; //завершение программы
}
//--------------------------------------------------------------------------Комментарии, написанные курсивом, характеризуют назначение каждого
раздела. Все описанные в головном файле операторы заносятся в него автоматически в процессе проектирования приложения. Так, что обычно ничего в головном файле изменять не надо и даже нет необходимости его смотреть. Вы
можете конечно занести в головной файл программы и другие операторы,
функции и т. д., но это будет плохой стиль программирования, поскольку это
противоречит принципу модульности. Все необходимые для начала выполнения программы операторы и процедуры целесообразно размещать в отдельном
модуле формы или в отдельный модуль без формы и включить его в приложение. Такой модуль можно включить в приложение, выполнив команду
File | New | Other и щелкнув по пиктограмме Unit.
Ниже приведены тексты заголовочного файла (расширение .h), содержащего описание класса формы, и файла реализации (расширение .cpp).
Комментарии в этих текстах поясняют, что и куда в этот код можно добавлять.
Заголовочный файл модуля формы
//--------------------------------------------------------------------------#ifndef UnRis1H
#define UnRis1H
//--------------------------------------------------------------------------// сюда могут помещаться дополнительные директивы препроцессора( в
частности, include), не включаемые в файл автоматически
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Buttons.hpp>
#include <ExtCtrls.hpp>
#include <math.h>
//--------------------------------------------------------------------------//
class TForm1 : public TForm
{
__published:
// IDE-managed Components
7
//приводятся, размещенные на форме компоненты
TImage *Image1;
TBitBtn *BitBtn1;
TImage *Image2;
TLabel *Label1;
TLabel *Label2;
TLabel *Label3;
TButton *Button1;
TButton *Button2;
//функции обработки событий
void __fastcall BitBtn1Click(TObject *Sender);
void __fastcall Button1Click(TObject *Sender);
void __fastcall Button2Click(TObject *Sender);
private:
// User declarations
// закрытый раздел класса, сюда могут помещаться объявления
//типов, переменных, функций, включаемых в класс форм и
//не доступных для других модулей
public:
// User declarations
//открытый раздел класса, сюда могут помещаться объявления
//типов, переменных, функций, включаемых в класс форм и
// доступных для других модулей
__fastcall TForm1(TComponent* Owner);
};
//--------------------------------------------------------------------------extern PACKAGE TForm1 *Form1;
// сюда могут помещаться объявления типов, переменных,
// функций, которые не включаются в класс форы; доступ к ним из // других блоков возможен только при соблюдении некоторых
//дополнительных условий
//--------------------------------------------------------------------------#endif
Файл реализации модуля
//--------------------------------------------------------------------------#include <vcl.h>
#pragma hdrstop
#include "UnRis1.h"
//--------------------------------------------------------------------------#pragma package(smart_init)
#pragma resource "*.dfm"
//сюда могут помещаться дополнительные директивы
// препроцессора (в частности, include),
// не включаемые в файл автоматически
// объявление объекта формы Form1
TForm1 *Form1;
8
//--------------------------------------------------------------------------// вызов конструктора формы
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
// сюда могут помещаться операторы, которые должны
// выполняться при создании формы
}
//--------------------------------------------------------------------------// сюда могут помещаться объявления типов и переменных,
// доступ к которым из других модулей возможен только
// при соблюдении некоторых дополнительных условий; тут
// же должны быть реализации всех функций, объявленных в
// заголовочном файле, а также могут быть реализации
// любых дополнительных функций, не объявленных ранее функций обработки событий
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
const float Pi= 3.14159;
float x, y; //координаты точки функции
int px,py; // Координаты пиксела, соответствующие
//точки с координатами x,y
for (px = 0; px <= Image1->Width; px++)
{
//x – координата, соответствующая пикселу с координатой px
x = px*4 * Pi/Image1->Width;
y = sin(x);
// y - координата пиксела, соответствующая координате y
py = Image1 -> Height - (y + 1)* Image1 -> Height/2;
// устанавливается черный цвет выбранного пиксела
Image1->Canvas-> Pixels[px][py] = clBlack;
}
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button2Click(TObject *Sender)
{
Form1->Close();
}
//--------------------------------------------------------------------------Имена файлам модулей C++ Builder дает по умолчанию: для первого модуля оно равно Unit1, для второго Unit2 и т. д. Если в приложении несколько
модулей следует сохранять их под какими-то осмысленными именами, изменяя
тем самым имена модулей, заданных по умолчанию.
9
1.3. Области видимости переменных и функций в
программах на C++ Builder
1. Переменные, объявленные в заголовочном файле модуля или в файле
его реализации вне описания класса и функций, являются глобальными [1]. Они
доступны везде внутри данного модуля. Для доступа к ним из внешних модулей в этих модулях должно быть повторено их объявление (без инициализации)
с добавлением спецификации extern.
2. Функции, объявленные в заголовочном файле модуля вне описания
класса, являются глобальными. Они доступны везде внутри данного модуля.
Для доступа к ним из внешних модулей в этих модулях или надо повторить их
объявление, или включить директивой #include в заголовочный файл того модуля, в котором функции описаны.
3. Функции, объявленные в файле реализации модуля, являются глобальными. Они доступны везде внутри данного модуля. Для доступа к ним из
внешних модулей в этих модулях надо повторить их объявление.
4. Элементы (переменные и функции), объявленные в классе в разделе
private, видимы и доступны только внутри данного модуля. При этом из функций, объявленных внутри класса, к ним можно обращаться непосредственно по
имени, а из других функций – только со ссылкой на объект данного класса. Если в модуле описано несколько классов, то объекты этих классов взаимно видят
элементы, описанные в их разделах private.
5. Элементы, объявленные в классе в разделе public, видимы и доступны
для объектов любых классов и для других модулей, в которых директивой #include включен заголовочный файл данного модуля. При этом из объектов того
же класса к ним можно обращаться непосредственно по имени, а из других
объектов и процедур – только со ссылкой на объект данного класса.
6. В классах, помимо обсуждавшихся ранее, могут быть еще разделы protected – защищенные. Элементы, объявленные в классе в разделе prоtected видимы и доступны для любых объектов внутри данного модуля, а также для объектов классов – наследников данного класса в других модулях. Объекты из других модулей, классы которых не являются наследниками данного класса, защищенных элементов не видят.
7. Элементы, объявленные внутри функции или блока являются локальными, т. е. они видимы и доступны только внутри данной функции или данного
блока. При этом время жизни переменных, объявленных внутри функции или
блока, определяется временем активности данного блока. Сделать локальную
переменную существующей постоянно можно с помощью спецификации static.
8. Переменные и функции, объявленные в головном файле проекта, являются глобальными для этого файла. Если требуется доступ к ним из других
модулей, то для функций в них должны быть повторены их объявления, а для
переменных – повторено объявление (без инициализации) со спецификацией
extern.
10
9. Если во внутреннем блоке, обозначаемом как {}, объявлена переменная с тем же именем, что во внешнем блоке, или с тем же именем, что и глобальная переменная, то соответствующая внешняя или глобальная переменная
в блоке не видна. В этом случае получить доступ к одноименной глобальной
переменной можно только с помощью унарной операции разрешения области
действия (::).
Более подробные сведения об областях видимости переменных и функций вы можете найти в [2].
1.4. Основные рекомендации для разработки программ
Стиль
Используйте осмысленные имена для глобальных переменных и короткие
– для локальных.
Будьте последовательны.
Используйте активные имена для функций.
Будьте точны.
Форматируйте код, подчеркивая его структуру.
Используйте естественную форму выражений.
Используйте скобки для устранения неясностей.
Разбивайте сложные выражения.
Будьте проще.
Будьте осторожны с побочными эффектами.
Будьте последовательны в применении отступов и фигурных скобок.
Используйте идиомы для единства стиля.
Используйте else-if для многовариантных ветвлений.
Избегайте макрофункций.
Заключайте тело макроса и аргументы в скобки.
Давайте имена загадочным числам.
Определяйте числа как константы, а не как макросы.
Используйте символьные константы, а не целые.
Используйте средства языка для определения размера объекта.
Не пишите об очевидном.
Комментируйте функции и глобальные данные.
Не комментируйте плохой код, а перепишите его.
Не противоречьте коду.
Вносите ясность, а не сумятицу.
Интерфейсы
Прячьте детали реализации.
Ограничьтесь небольшим набором независимых примитивов.
Не делайте ничего «за спиной» у пользователя.
Всегда делайте одинаковое единообразно.
11
Высвобождайте ресурсы на том же уровне, на котором выделяли их.
Обнаруживайте ошибки на низком уровне, обрабатывайте – на высоком.
Используйте исключения только для исключительных ситуаций.
Отладка
Ищите знакомые ситуации.
Проверьте самое последнее изменение.
Не повторяйте дважды одну и ту же ошибку.
Не откладывайте отладку на потом.
Пользуйтесь стеком вызова.
Читайте код перед тем, как исправлять.
Объясните свой код кому-либо еще.
Сделайте ошибку воспроизводимой.
Используйте принцип: Разделяй и властвуй.
Изучайте нумерологию ошибок.
Выводите информацию, локализующую место ошибки.
Пишите код с самоконтролем.
Ведите журнальный файл.
Постройте график.
Используйте инструменты.
Ведите записи.
Тестирование
Тестируйте граничные условия кода.
Тестируйте пред- и постусловия.
Используйте утверждения.
Используйте подход защитного программирования.
Проверяйте коды возврата функций.
Тестируйте по возрастающей.
Тестируйте сначала простые блоки.
Четко определите, чего вы хотите на выходе текста.
Проверяйте свойства сохранности данных.
Сравните независимые версии.
Оценивайте охват тестов.
Автоматизируйте возвратное тестирование.
Создайте замкнутые тесты.
Производительность
Автоматизируйте замеры времени.
Используйте профилировщик.
Концентрируйтесь на критических местах.
Постройте график.
Улучшайте алгоритм и структуру данных.
Используйте оптимизацию компилятора.
Выполните тонкую настройку кода.
12
Не оптимизируйте то, что не имеет значения.
Объединяйте общие выражения.
Замените дорогостоящие операции на более дешевые.
Избавьтесь от циклов или упростите их.
Кэшируйте часто используемые значения.
Напишите специальную функцию захвата памяти (аллокатор).
Буферизуйте ввод и вывод.
Специальные случаи обрабатывайте отдельно.
Используйте предварительное вычисление результатов.
Используйте приближенные значения.
Перепишите код на языке более низкого уровня.
Используйте минимально возможный тип данных.
Не храните то, что можете без труда вычислить.
Переносимость
Придерживайтесь стандарта.
Следуйте основному руслу.
Избегайте неоднозначных конструкций языка.
Попробуйте несколько компиляторов.
Используйте стандартные библиотеки.
Используйте только то, что доступно везде.
Избегайте условной компиляции.
Выносите системные различия в отдельные файлы.
Прячьте системные различия за интерфейсами.
Используйте текст для обмена данными.
Используйте при обмене данными фиксированный порядок байтов.
При изменении спецификации изменяйте и имя.
Поддерживайте совместимость с существующими программами и данными.
Не рассчитывайте на ASCII.
Не ориентируйтесь только на английский язык.
2. ЛАБОРАТОРНАЯ РАБОТА № 1
Тема: «Изучение среды программирования C++ Builder. Программирование и отладка простейших программ».
Цель работы: Изучение среды программирования на языке C++ Builder и
освоение ее основных возможностей. Изучение стандартных типов данных, выражений и операций, стандартных компонентов среды программирования и их
применение для визуальной разработки программ [1].
Задачи. Разработать алгоритм и программу на языке С++ Builder решения вычислительной задачи для диапазона значений исходных данных с
использованием стандартных компонентов среды программирования для
разработки интерфейса пользователя.
13
2.1. Разработка алгоритма решения задачи
Последовательность разработки алгоритма решения задачи.
Определение внешней спецификации задачи.
Пусть в результате математической формализации поставленной задачи
на разработку программного средства определено, что необходимо вычислить координаты точки, делящей отрезок [a1, a2] в отношении n1:n2 по формулам:
x = (x1 + vx2) / (1 + v); y = (y1 + vy2) / (1 + v),
где v = n1 / n2; x1, y1 – координаты точки a1; x2, y2 – координаты точки a2.
Исходными данными для решения задачи являются:
– x1, y1 – координаты начальной точки и x2, y2 – координаты конечной
точки, которые могут принимать как положительные, так и отрицательные
целые и вещественные числа;
– значения величин n1 и n2, которые могут быть только положительными целыми либо вещественными числами.
Выходными данными являются координаты x, y точки, делящей отрезок
в отношении n1/n2. Так как в формулах присутствует операция деления, то
значения x и y будут вещественными числами.
В зависимости от квалификации разработчика алгоритм решения данной задачи может иметь различную структуру. В процессе обучения построим алгоритм простейшей структуры.
Для каждой конкретной зависимости, при этом, возможна своя (требуемая) степень детализации.
Алгоритм можно считать оптимальным, если степень детализации обеспечивает приемлемый объём и наглядность, а также простоту отладки при р ешении и удобство анализа результатов.
Так, для данной задачи определения координат x, y точки, делящей отрезок в заданном отношении, расчеты могут проводиться в следующей последовательности:
1. Рассчитываем коэффициент v: v = n1 / n2.
2. Рассчитываем значение величины b = (1 + v).
3. Рассчитываем значение координаты x по формуле:
x = (x1 + vx2) / b.
4. Рассчитываем значение координаты y по формуле:
y = (y1 + vy2) / b.
Графическое изображение алгоритма может быть представлено в виде
рис. 2.1.
14
Начало
x1, y1, x2, y2, n1, n2
v = n1 / n2
b=1+v
x = (x1 + v * x2) / b
y = (y1 + v * y2) / b
Вывод
x, y
Конец
Рис. 2.1. Схема алгоритма решения задачи
Рис. 2.2. Страница New окна депозитария New Items
15
2.2. Разработка проекта на языке С++ Builder
Начать новый проект можно несколькими способами:
1. Команда New | File | Application.
2. Команда New | File | Other.
3. Кнопка быстрого вызова
на панели инструментов.
При выборе этой команды открывается окно депозитария New
Items, хранящее образцы компонентов, форм и проектов (ри с. 2.2.).
2.3. Разработка интерфейса пользователя
Запустите С++ Builder, выбрав в меню Borland C++ Builder 6 команду
С++Builder 6, и в меню Файл выберите команду New | File | Application, либо в появившемся окне типовых вариантов разработки проектов выберите ярлык Стандартные. На экране дисплея появится главное окно среды программирования на
языке Borland C++ Builder 6, вид которого представлен на рис. 2.3.
Панель инструментов
Меню
Панель компонентов
Структура
проекта
Форма
Инспектор
объектов
Окно редактирования
кода
Рис. 2.3. Главное окно среды программирования Borland C++ Bilder 6
16
В верхней части главного окна размещены: меню, настраиваемая панель
инструментов (слева) и палитра компонентов (справа). В средней части окна
размещены панель Инспектора объектов (слева) и форма нового приложения
(справа). Форма почти полностью закрывает окно редактора кода. На палитре
компонентов, выполненной в виде многостраничного блокнота, размещены объекты (компоненты), используемые при визуальном проектировании программы.
Формы являются основой приложений C++ Builder и представляют собой
заготовку окна интерфейса пользователя разрабатываемой программы. Создание пользовательского интерфейса программы заключается в добавлении в о кно формы объектов из панели компонентов. Каждому объекту присущи определенные свойства, характеризующие его вид, положение и поведение. Для редактирования свойств объектов предназначена панель Инспектора объектов.
Перечень и свойства объектов палитры компонентов приводятся в приложении
к пособию.
Работа над новым проектом начинается с создания стартовой формы.
Стартовая форма создается путем изменения значений свойств формы и размещения на форме необходимых объектов (полей ввода исходных данных, полей
вывода результатов расчетов и текстовой информации для пользователя).
Разрабатываемый проект, входящие в его состав формы и объекты должны иметь уникальное, отражающее их назначение имя, позволяющее найти их в
каталоге и обращаться к ним в программе. Поэтому первой операцией после
открытия окна проекта, является присвоение проекту и стартовой форме имени.
Для этого выполните следующие действия.
В меню файл выберите опцию Сохранить проект как…. В открывшемся окне создайте папку, в которой будут сохраняться все файлы проекта, откройте ее, дайте название проекту LAB1, нажмите ОК. В открывшемся
окне дайте имя стартовой форме Frm1Lab1, нажмите ОК. Теперь проект и
форма будут сохранены в выбранной Вами папке, и Вы сможете открыть ее
в случае «зависания» компьютера.
Внимание. В течение работы над проектом не забывайте периодически сохранять проект, так как в среде программирования Borland C++ Builder
6 не реализуется режим автосохранения, и в случае сбоя компьютера результаты текущей разработки программы могут быть уничтожены.
2.4. Выбор визуальных объектов для стартовой формы
Для конструирования стартовой формы разместим на ней следующие
объекты из палитры компонентов:
– метки (Label) для вывода информации для пользователей;
– текстовые окна (Edit) для ввода исходных данных;
– командные кнопки (Button) для передачи в программу команд.
В соответствии с изложенным разместим на форме следующие объекты:
Label1 (метка) – для размещения названия работы;
17
Label2 – для размещения фамилии и имени исполнителя;
Label3 – для размещения содержания решаемой задачи;
Edit1 – текстовое окно для ввода значения координаты x1 точки a1;
Edit2 – текстовое окно для ввода значения координаты y1 точки a1;
Edit3 – текстовое окно для ввода значения координаты x2 точки a2;
Edit4 – текстовое окно для ввода значения координаты y2 точки a2;
Edit5 – текстовое окно для ввода значения n1;
Edit6 – текстовое окно для ввода значения n2.
Для информирования пользователя о том, в какое окно какие исходные
данные вводить необходимо возле каждого текстового окна разместить метку с
соответствующей информацией.
Label4 – для указания, в данное окно вводится значение x1;
Label5 – для указания, в данное окно вводится значение y1;
Label6 – для указания, в данное окно вводится значение x2;
Label7 – для указания, в данное окно вводится значение y2.
Для вывода результатов расчета разместим четыре метки: две метки – для
указания, какие данные выводятся и две метки – для вывода значений результатов расчета:
Label8 – для указания, в данное окно выводится значение x;
Label9 – для указания, в данное окно выводится значение y;
Label10 – для вывода значения x2;
Label11 – для вывода значение y2.
Для того, чтобы разместить на форме объекты, надо в палитре компонентов, на вкладке Standard, щелкнуть на значке выбранного объекта (рис. 2.4),
установить курсор в ту точку формы, в которой должен быть левый верхний
угол объекта, и еще раз щелкнуть кнопкой мыши. В результате на форме появится выбранный компонент. Объект можно перемещать, изменять его размеры и другие характеристики.
метка
текстовое
окно
Командная
кнопка
Рис.2.4. Выбор объектов в палитре компонентов. Компоненты C++ Builder
2.5. Задание свойств объектов
Каждый объект C++ Builder имеет три разновидности характеристик: свойства, события и методы. Если выбрать компонент из палитры и добавить его к
форме либо выделить его на форме щелчком мыши, инспектор объектов автоматически покажет в окне инспектора объектов свойства и события (рис. 2.5), кото-
18
рые могут быть использованы этим объектом. В верхней части инспектора объектов имеется выпадающий список (селектор объектов), позволяющий выбирать
нужный объект из имеющихся на форме.
Свойства объектов. Свойства являются атрибутами компонента, определяющими его внешний вид и поведение. Многие свойства компонента в колонке
свойств имеют значение, устанавливаемое по умолчанию. Свойства компонента
отображаются на странице свойств (Properties) Инспектора объектов (рис. 2.5) и
используются для установки свойств во время проектирования. Можно определить свойства во время проектирования или написать код для видоизменения
свойств компонента во время выполнения приложения. Перечень свойств объектов, используемых в лабораторных работах, приведен в приложении.
Страница свойств объектов
Страница событий объектов
Рис. 2.5. Инспектор объектов
Для задания свойств объекта во время проектирования нужно выбрать
объект, размещенный на форме, открыть страницу свойств в инспекторе объектов, выбрать определяемое свойство и изменить его с помощью редактора
свойств (это могут быть простое поле для ввода текста или числа, выпадающий
список, раскрывающийся список, диалоговая панель и т. д.).
19
Последовательность действий при размещении объектов на форме и задании им свойств состоит в следующем:
1. Щелкните левой клавишей мыши по значку Label (рис. 2.5) на панели
компонентов. Переместите курсор на верхнюю часть формы и нажмите на левую клавишу мыши и, перемещая курсор, растяните прямоугольник метки
нужного размера.
2. Откройте Инспектор объектов, если его нет на рабочем столе, выбрав
в меню Вид опцию Инспектор объектов. В верхней части окна должно быть
имя (по умолчанию) созданного объекта Label1.
3. Откройте страницу свойств, щелкнув по закладке Properties и в открывшемся списке выберите свойство Name. Измените имя объекта, присвоенного ему по умолчанию на более содержательное, позволяющее его опознать
среди множества других объектов такого же класса, для этого выделим в Инспекторе объектов свойство Name и в открывшемся справа поле наберем имя
LabTitul.
4. Выделите свойство Caption (Надпись) и в открывшемся поле наберем
следующий текст Лабораторная работа 1. Выберем свойство Font, в поле
справа щелкнем мышкой по стрелке и в открывшемся окне Шрифт установим
имя шрифта – MS San Sarif, начертание – обычное, размер – 14, цвет – синий.
Установим размер окна AutuSize (автоматический размер) в значение – true.
5. Аналогичным способом создайте метки Label2 – Label14 и текстовые
окна Edit1 – Edit6 и задайте указанным объектам значения свойств, указанных в
табл. 2.1.
Таблица 2.1
Создание меток и текстовых окон
с заданием указанным объектам значений свойств
Объекты
Label1
Name
LabTit
Label2
LabName
Label3
LabCap
Label4
Labx1
Label5
Laby1
Свойства
Caption
Font
Лабораторная работа 1
Имя – MS San Sarif
Начертание – Обычное
Размер – 16
Цвет – синий
Изучение приемов раз- MS San Sarif
работки программы на Начертание – Обычное
языке C++ Builder
Размер – 14
Цвет – красный
Выполнил: студент Пет- MS San Sarif
ров П. П.
Начертание – Обычное
Размер – 12
Цвет – зеленый
Координата x1
MS San Sarif
Начертание – Обычное
Размер – 12
Цвет – черный
Координата y1
MS San Sarif
Начертание – Обычное
Размер – 12
20
Цвет – черный
Продолжение табл. 2.1
Свойства
Объекты
Label6
Name
Labx2
Caption
Координата x2
Label7
Laby2
Координата y2
Label8
Labn1
Значение n1
Label9
Labn2
Значение n2
Label10
LabRezult
Результаты расчета
Label11
LabX
Координата x
Label12
Laby
Координата y
Label13
LabZnx
пусто
Label14
LabZny
пусто
Edit1
Editx1
Нет такого свойства
Edit2
Edity1
Нет такого свойства
Edit3
Editx2
Нет такого свойства
21
Font
MS San Sarif
Начертание – Обычное
Размер – 12
Цвет – черный
MS San Sarif
Начертание – Обычное
Размер – 12
Цвет – черный
MS San Sarif
Начертание – Обычное
Размер – 12
Цвет – черный
MS San Sarif
Начертание – Обычное
Размер – 12
Цвет – черный
MS San Sarif
Начертание – Обычное
Размер – 12
Цвет – синий
MS San Sarif
Начертание – Обычное
Размер – 12
Цвет – синий
MS San Sarif
Начертание – Обычное
Размер – 12
Цвет – синий
MS San Sarif
Начертание – Обычное
Размер – 12
Цвет – синий
MS San Sarif
Начертание – Обычное
Размер – 12
Цвет – синий
MS San Sarif
Начертание – Обычное
Размер – 12
Цвет – черный
MS San Sarif
Начертание – Обычное
Размер – 12
Цвет – черный
MS San Sarif
Начертание – Обычное
Размер – 12
Цвет – черный
Окончание табл. 2.1
Объекты
Edit4
Свойства
Name
Edity2
Caption
Нет такого свойства
Edit5
Editn1
Нет такого свойства
Edit6
Editn2
Нет такого свойства
Buton1
ButBig
Вычислить
Buton2
ButOut
Выход
Font
MS San Sarif
Начертание – Обычное
Размер – 12
Цвет – черный
MS San Sarif
Обычное
Размер – 12
Цвет – черный
MS San Sarif
Начертание – Обычное
Размер – 12
Цвет – черный
Начертание – Обычное
Размер – 12
Цвет – черный
Начертание – Обычное
Размер – 12
Цвет – черный
После размещения перечисленных объектов на форме она должна иметь
вид, подобный приведенному на рис. 2.6.
22
Рис. 2.6. Вид стартовой формы разрабатываемого проекта
2.6. Написание кода программы
Для запуска программы, разработанной на объектно-ориентированных
языках необходима инициализация какого-либо события, которое распознается
объектом. Это может быть щелчок мышью по объекту, наведение курсора на
объект и др.
Каждый компонент имеет свой собственный набор обработчиков событий. Страница событий (Events) инспектора объектов показывает список событий, распознаваемых тем или иным объектом.
В C++ Builder следует писать функции программы, связывать их с событиями объектов. Создавая функцию для того или иного события, Вы поручаете
программе выполнить написанную функцию, если это событие произойдет.
Для того, чтобы написать функцию для события, нужно выбрать на форме
с помощью мыши объект, который будет распознавать событие, затем о ткрыть
страницу событий инспектора объектов и дважды щелкнуть левой клавишей
мыши на колонке значений рядом с событием, чтобы заставить C++ Builder сгенерировать заготовку (шаблон) функции и показать его в редакторе кода. При
этом автоматически генерируется текст пустой функции, и редактор открывается
в том месте, где следует вводить код. В верхней части заготовки указывается имя
функции, содержащее имя объекта и имя события, при возникновении которого
начнет выполняться функция. Функция события может иметь параметры, которые указываются после имени функции в круглых скобках.
Курсор позиционируется внутри операторных скобок { ... }, где пишется
код функции (рис. 2.7). Далее нужно ввести код, который должен выполняться
при наступлении события.
//Здесь пишется код функции для события Click командной кнопки
Рис. 2.7. Заготовка для написания функции для события
«Щелчок мышью по командной кнопке»
Последовательность написания кода функции аналогична написанию
23
Тип
char
Размер в
байтах
функций в языке С++ и состоит из следующих этапов:
1. Выделите командную кнопку Вычислить и в диспетчере объектов откройте закладку Events и дважды щелкните мышью по строке с событием Click.
Откроется окно редактирования кода с заготовкой функции, и курсор будет мигать в том месте, где необходимо писать код функции.
2. Объявите переменные с указанием их типов. Синтаксис объявления:
[определение типа] [список идентификаторов переменных];
Список идентификаторов может состоять из нескольких идентификаторов переменных, разделенных запятыми.
Например:
int x1, x2, b;
unsigned char c1, b2; .
Ниже приводится сводная таблица встроенных стандартных типов данных C++ Builder (табл. 2.2):
Таблица 2.2
Сводная таблица встроенных стандартных типов данных C++ Builder
1
unsigned char
1
short
unsigned short
enum
long
unsigned long
int
Unsigned int
float
double
Long double
bool
2
2
2
4
4
4
4
4
8
10
1
Название
Диапазон значений
короткое целое
От –128 до +128
со знаком
короткое
от 0 до + 255
положительное
целое
целое со знаком
от – 32 768 до +32 767
положительное
от 0 до 65 535
целое
длинное целое
от – 2 147 483 648
со знаком
до +2 147 483 647
длинное целое
от – 2 147 483 648
со знаком
до +2 147 483 647
положительное длин- от 0 до 4 294 967 295
ное целое
длинное целое
от – 2 147 483 648
со знаком
до +2 147 483 647
положительное длин- от 0 до 4 294 967 295
ное целое
действительное
от – 3,4 * 1038 до –3,4 * 10- 38 от
+3,4 * 10- 38 до + 3,4* 1038
действительное двойной от – 1,7*10308 до –1,7* 10-308
точности
от +1,7* 10-308 до +1,7*10308
длинное
от -1,1*104932 до –3,4 *10- 4932 от 3,4
действительное
*10- 4932 до +1,7* 10-308
булев тип
true или false; 1 или 0
24
Именованные константы объявляются так же, как переменные, но с добавлением слова const. Например:
const float Pi = 3.14159;
Для рассматриваемой задачи объявление переменных может быть записано в виде:
float x1, y1; // координаты точки a1
float x2, y2; // координаты точки a2
float n1, n2; // переменные определяющие соотношение,
//в котором делится отрезок a1 a2
float x, y; // Координаты точки, делящей отрезок на две части.
int v, b ; // вспомогательная переменная
3. Напишем код для считывания исходных данных из текстовых окон и
присваивания их объявленным переменным.
Для ввода исходных данных в окно Edit используется свойство Text.
Поэтому для считывания исходных данных надо написать выражение обращения к свойству Text. Синтаксис обращения к свойству объекта имеет вид:
[имя объекта] -> [ имя свойства].
Внимание. Данные, введенные в текстовые окна, принимают строковый
тип, поэтому при их считывании в переменную числового типа необходимо их
преобразовывать в числовой тип, а при программной записи в текстовое окно
числовых данных их необходимо преобразовывать в строковый тип. Для такого
преобразования используются функции:
StrToFloat (…) – преобразование строкового типа в числовой.
FloatToStr(…) – преобразование числового типа в строковый.
Для рассматриваемой задачи это будут следующие выражения:
x1 = StrToFloat(Editx1->Text);
y1 = StrToFloat(Edity1->Text);
x2 = StrToFloat(Editx2->Text);
y2 = StrToFloat(Edity2->Text);
n1 = StrToInt(Editn1->Text);
n2 = StrToInt(Editn2->Text);
Таблица 2.3
Бинарные операции в языке С++
Обозначение
Операция
+
–
*
/
Сложение
Вычитание
Умножение
Деление
Остаток целочисленного
деления
Унарный плюс
%
+
25
Типы операндов и
результата
арифметические
арифметические
арифметические
арифметические
целые
арифметические
Пример
a+b
a–b
a*b
a/b
a%b
+a
–
Унарный минус
арифметические
–a
4. Теперь напишем код функции в соответствии с составленным алгоритмом.
Решение рассматриваемой задачи осуществляется с использованием
арифметических операций. Арифметические операции применяются к действительным числам, целым числам и указателям. В языке С++ определены следующие бинарные операции (табл. 2.3).
Для арифметических операций действуют следующие правила.
1. В процессе вычисления автоматически осуществляется преобразование типов по принципу: если операция имеет операнды разных типов, то тип
операнда «младшего» типа приводится к «операнду» старшего типа. Иначе говоря , менее точный тип приводится к более точному типу. Например, если в
операции участвуют короткое целое и длинное целое, то короткое приводится к
длинному; если участвуют целое и действительное (вещественное), то целый
операнд приводится к действительному.
2. Бинарные операции сложения и вычитания применимы к целым и действительным числам, а также к указателям.
3. В операциях умножения и деления операнды могут быть любых арифметических типов.
4. В операции вычисления остатка от деления оба операнда должны быть
целыми числами.
5. В операциях деления и вычисления остатка второй операнд не может
быть равен нулю.
6. Если оба операнда в этих операциях целые, а результат деления является не целым число, то знак результата вычисления остатка совпадает со знаком
первого операнда, а для операции деления используются следующие правила:
7. Если первый и второй операнды имеют одинаковые знаки, то результат
операции деления – наибольшее целое, меньшее истинного результата деления.
8. Если первый и второй операнды имеют разные знаки, то результат
операции деления – наименьшее целое, большее истинного результата деления.
9. Округление всегда осуществляется по направлению к нулю.
Все это относится к арифметическим операциям, но не относится к операциям присваивания. При присваивании осуществляется автоматическое приведение типа результата арифметической операции к типу левого операнда. Это
можно исправить применив операцию явного приведения типов. Она записывается в виде (тип операции):
Например:
Int m = 1, n = 2;
double a = m / n; // результат равен 0, не верно, но:
double a = double m / n; //результат равен 0,5, верно.
Код алгоритма решаемой задачи может быть записан в виде:
v = (float) n1 / n2; // так как при делении целых чисел
26
//результат округляется до целого, то применимо
//принудительное преобразование
//переменных целого типа в действительный тип
b = 1 + v;
x = (x1 + v*x2) / b;
y = (y1 + v*y2) / b;
5. Напишем код выражений для вывода полученных результатов в заранее подготовленные поля меток LabZnx и LabZny, используя поле свойства Caption.
LabZnx -> Caption = FloatToStr(x);
LabZny -> Caption = FloatToStr(y);
6. Напишем функцию для события «Щелчок мышью по командной
кнопке «Выход», позволяющей выйти из программы.
Для этого выделим командную кнопку Выход, в окне диспетчера задач откроем закладку Events, щелкнув дважды по строке Click и в открывшемся окне редактора кода напишем следующее выражение:
FrmLab1 -> Close();
В данном выражении происходит обращение к методу Close (закрывать), который может реализовываться формой.
Метод является функцией, которая связана с объектом, и которая объявляется как часть объекта. Создавая обработчики событий, можно вызывать методы, используя следующую нотацию: ->, например:
Edit1->Show(); // показывать.
Данных действий достаточно, чтобы считать программу решения поставленной задачи в первом приближении составленной!
2.7. Сохранение проекта
Проект – это набор файлов, используя которые компилятор создает выполняемый файл программы (.exe-файл). Чтобы сохранить проект, нужно в
меню File выбрать команду Save Project As. Если проект еще ни разу не был
сохранен, то C++ сначала предложит сохранить модуль (содержимое окна
редактирования кода) и поэтому на экране появится окно Save Unit As. В этом
окне надо выбрать папку, предназначенную для проектов, создать в ней папку для сохранения данного проекта, открыть ее и ввести имя модуля. В р езультате щелчка на кнопке Сохранить в указанной папке будут созданы три
файла с расширениями: .cpp, .h и .dfm, и на экране появится диалоговое окно
Save Project As, в которое надо ввести имя проекта.
Внимание! Имена файла модуля (.cpp) и файла проекта (.bpr) должны
быть разные, так как в момент сохранения файла проекта создается одноименный файл головного модуля, имеющего то же расширение (.cpp).
27
2.8. Компиляция программы
На этапе преобразования исходной программы в выполняемую производятся компиляция и компоновка программы. Компиляция переводит исходную программы, написанную на языке программирования в некоторое
внутреннее машинное представление, а при компоновке производится сборка
программы. Для компиляции программы выберите в меню Project команду
Compile. Процесс и результат компиляции отражается в диалоговом окне
Compiling (рис. 8). Если в программе нет синтаксических ошибок, то окно
будет содержать сообщение: Done: Compile Uni;, в противном случае будет
выведено сообщение: Done: There are errors и дана информация о количестве
синтаксических (Errors) и семантических ошибок (Warnings), а так же о числе подсказок (Hints). Чтобы перейти к фрагменту кода, надо выбрать сообщение об ошибке и выбрать команду Edit Source. Процесс компиляции можно
запустить во время разработки и отладки программы, выбрав в меню Run команду Run или щелкнуть по значку
на панели инструментов.
2.9. Отладка и тестирование программы
В большинстве случаев в только что набранной программе встречаются
ошибки. Компилятор переходит к компоновке в том случае, если исходный
текст не содержит ошибок, поэтому программист должен их устранить. Вначале надо устранить очевидные ошибки, например, используются необъявленные
переменные. Для типичных ошибок компилятор выводит сообщения. Некоторые из них приведены в табл. 2.4.
Таблица 2.4
Сообщения компилятора для типичных ошибок
№ п/п
1
2
3
4
5
6
7
Сообщения
Ошибка
Undefined symbol (неиз- Используется необъявленная переменная. Имя певестный параметр)
ременной, функции или параметра написано неверно.
Statement missing ;
После инструкции не поставлена точка с запятой.
Unterminated string of В конце строковой константы, например, текста соcharacter constant
общения, нет двойных кавычек.
) expected
При записи арифметического выражения нарушен
баланс открывающих и закрывающих скобок.
If statement missing (Нет В инструкции if условие не заключено
закрывающей скобки)
в скобки.
Compound
statement Нарушен баланс открывающих и
missing
закрывающих фигурных скобок.
Вероятно, не поставлена закрывающая скобка,
отмечающая конец функции или группы инструкций, например, после
условия или слова else в инструкции if.
Extra parameter in call to Наверно записана инструкция вызова функции,
(лишний параметр при
указан лишний параметр.
вызове функции)
28
После отладки программы необходимо провести тестирование пр ограммы, используя контрольные исходные данные и полученные для них
результаты расчетов, проведенных другими способами.
Если программа показывает результаты расчета, совпадающие с контрольными расчетами, можно считать, что программа составлена верно.
Пример 2. Пример разработки программы с использованием библиотеки
стандартных математических функций.
Условие задачи: В треугольнике заданы две стороны а, b и угол напротив
одной из них А (рис. 2.8). Определить сторону с, углы В и С и площадь треугольника S (Исходные данные вводить в текстовые окна, результаты выводить
в метки, линейные размеры вводить и выводить в см, площадь – в см2, углы – в
градусах).
1.
Определение внешней спецификации задачи.
Исходные данные: a, b – стороны треугольника, вещественные положительные числа; A – угол, вещественное положительное число в диапазоне 0 <
A < 180 град.
B
A
c
A
a
A
Рис. 2.8. Схема
b
a
треугольника
A
для
C
\
C
примера
A
2
Результаты решения задачи:
B – угол, вещественное положительное число в диапазоне 0 < B < 180 град. C –
угол, вещественное положительное число в диапазоне 0 < C < 180 град.; с – сторона
треугольника, вещественное положительное число; S – площадь треугольника, вещественное число.
2. Определение требования к интерфейсу пользователя:
Интерфейс должен содержать три текстовых окна для ввода исходных
данных.
Три метки, поясняющие назначение этих окон.
Четыре текстовых окна для вывода результатов решения задачи.
Четыре метки, поясняющие назначение меток вывода результатов.
Командную кнопку для запуска программы на решение.
Командную кнопку для выхода из программы.
3. Выбор метода решения задачи:
Решение задачи основано на использовании тригонометрических формул:
из теоремы синусов: В = arcsin ((b / a) sin A);
сумма углов треугольника: 180° – С = 180 – (A + B);
из теоремы синусов: c = a (sin C / sin A);
29
S = 0.5 ab sin С.
4. Алгоритм решения задачи линейный.
Графическое изображение алгоритма может представлено на рис. 2.9.
Начало
a, b, A
B = arcsin*
(b / a * sin A)
С = 180 – (A + B)
c = a (sin * C / sin
A)
S = 0.5 * a * b * sin
С
Вывод
B, C, c, S
Конец
Рис.2.9. Схема алгоритма решения задачи
5. Проектирование интерфейса.
Создадим новый проект и на форме разместим требуемые объекты как
показано на рис. 2.10. размер шрифта для всех объектов можно установить в
свойстве Font формы. В этом случае все объекты формы будут наследовать
это свойство. Для текстовых окон следует в свойстве Техт удалить устано вленный по умолчанию текст Edit.
6. Написание кода программы.
Прежде, чем писать код, проанализируем используемые формулы.
Анализ показывает, что в формулах используются тригонометрические
функции y = sin (x), x = arcsin (y), где х – величина угла в радианах, а y изменяется в следующих пределах: 0 < y < 1.
Для пересчета рад. в град. и обратно используются формулы x (рад). =
180 * x (град) / π, и x (град). = π * x (рад) / 180.
30
Рис. 2.10. Интерфейс программы вычисления элементов треугольника
Следовательно, нам потребуется подключить файлы с математическими
и тригонометрическими функциями. Для их включения в проект откроем заголовочный файл модуля формы, щелкнув мышкой по закладке Unit1.h внизу
окна редактирования кодов и запишем директиву подключения файлов math.h
и Math.hpp, как показано ниже.
Заголовочный файл модуля формы
#ifndef UTreug1H
#define UTreug1H
//--------------------------------------------------------------------------#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <math.h >
#include <Math.hpp>
//--------------------------------------------------------------------------class TFtreug : public TForm
Выберем для командной кнопки событие Button1Click и напишем приведенный ниже код обработки события.
void __fastcall TFtreug::Button1Click(TObject *Sender)
{
float a, b, c, A,B,C,S;
const float e = 180;
float A1, B1, C1, d;
a =StrToFloat(Edit1->Text);
31
b=StrToFloat(Edit2->Text);
A= StrToFloat(Edit3->Text);
A1 = M_PI*A/180;
d = (b/a)* sin(A1);
B1 = ArcSin(d);
B = 180* B1/M_PI;
C =e-(A+B);
C1 = M_PI*C/180;
c=a*sin(C1)/sin(A1);
S= 0.5*a*b*sin(C1);
Edit4->Text = FloatToStr(B);
Edit5->Text = FloatToStr(C);
Edit6->Text = FloatToStr(c);
Edit7->Text = FloatToStr(S);
}
Для командной кнопки EXIT напишем следующую функцию обработки
события для выхода из программы.
void __fastcall TFtreug::Button2Click(TObject *Sender)
{
Ftreug-> Close();
}
Откомпилируем программу, введем контрольные исходные данные и
проверим работоспособность программы.
2.10. Задания для лабораторной работы № 1
Разработайте алгоритм, интерфейс пользователя, позволяющего вводить
именованные исходные данные и вывод результатов, и программу решения задачи:
Вариант 2.1. Площади треугольника со сторонами a, b, c по формуле Герона.
s p( p a)( p b)( p c) ,
где p = (a+ b + c)/2
Вариант 2.2. Площади поверхности усеченного конуса для заданных R, r, l.
S
R2
(R r)l
r2
Вариант 2.3. Объема усеченного конуса для заданных R, r, h:
V
(R2 r 2 Rr)h / 3
Вариант 2.4. Координаты центра тяжести трех материальных точек с массами
m1, m2, m3 и координатами (x1, y1), (x2, y2), (x3, y3):
m1x1 m2x2 m3x3
x
m1 m2 m3
m1y1 m2 y2 m3 y3 .
y
m1 m2 m3
32
Вариант 2.5. Площади трапеции, где а и b – длины оснований; h – высота
трапеции:
S 0,5(a b)h .
Вариант 2.6. Площади поверхности и объема цилиндра, где r – радиус основания, h – высота цилиндра:
S
2 * * r * (h r ) ; V
*r2 *h .
Вариант 2.7. Объема и площади поверхности шара радиуса r:
V (3 / 4) * * r 3 S 4 * * r 2 .
Вариант 2.8. Объема полого цилиндра:
V (r12 r22 ) h ,
2
2
где r1 – радиус цилиндра, r2 – радиус отверстия, h – высота цилиндра.
Вариант 2.9. Объема конуса высотой h и основанием радиуса r:
V
(1 / 3) * * r 2 * h .
Вариант 2.10. Величину тока, протекающего через цепь из двух параллельно соединенных сопротивлений r1 и r2 Ом при напряжении V вольт:
I V (r1 r2 ) / r1r2
Вариант 2.11. Площадь треугольника, если известны координаты вершин
его углов: a – x1, y1; b – x2, y2; c – x3, y3.
Вариант 2.12. Величину дохода по вкладу. Процентная ставка a % годовых и время хранения t дней задаются во время работы программы.
Вариант 2.13. Стоимость поездки на автомобиле на дачу (туда и обратно).
Исходными данными являются: расстояние до дачи L км; количество бензина,
которое потребляет автомобиль на 100 км пробега – v литров; цена одного литра бензина – с руб.
Вариант 2.14. Величину тока через цепь из двух последовательно соединенных сопротивлений, R1, R2 и напряжении сети – v в.
Вариант 2.15. Программу пересчета веса из фунтов в килограммы (один
фунт – это 405,9 грамма).
Вариант 2.16. Программу пересчета расстояния из километров в версты
(одна верста – это 1066,8 м).
Вариант 2. 17. В треугольнике (см. рис. 2.11 а) заданы две стороны а и b и
угол между ними С. Вычислить сторону с, углы А и В и площадь треугольника.
Вариант 2.18. В треугольнике (см. рис. 2.11 а) заданы сторона а и прилегающие к ней углы В и С. Вычислить стороны b, c и угол A треугольника.
Вариант 2.19. В треугольнике (см. рис. 2.11 а) заданы три стороны a, b и с.
Вычислить величины углов A, B, C треугольника.
Вариант 2.20. В треугольнике (см. рис. 2.11 а) заданы две стороны а, b и
площадь S. Вычислить сторону c, углы A, B, C треугольника.
33
Вариант 2.21. В треугольнике (см. рис. 2.11 а) заданы сторона а, угол С
и площадь S. Вычислить стороны b, c и углы A, и B треугольника.
Вариант 2.22. В треугольнике (см. рис. 2.11 а) заданы сторона b, угол А
и радиус описанной окружности R. Вычислить стороны a, c и углы B и C треугольника.
Вариант 2.23. В треугольнике (см. рис. 2.11 а) заданы углы А, В и радиус
описанной окружности R. Вычислить стороны a, b, c и угол C треугольника.
Вариант 2.24. В треугольнике (см. рис. 2.11 а) заданы стороны a, b и радиус описанной окружности R. Вычислить сторону c, и углы A, B, C треугольника.
Вариант 2.25. В треугольнике (см. рис. 2.11 а) заданы стороны a, b и половина периметра р. Вычислить сторону c и углы A, B, C треугольника.
Вариант 2.26. В треугольнике (см. рис. 2.11 а) заданы углы А, С и высота
hb. Вычислить стороны a, b, c и угол B треугольника.
Вариант 2.27. В треугольнике (см. рис. 2.11 а) заданы стороны а, с и высота hb. Вычислить сторону b и углы A, B, C треугольника.
Вариант 2.28. В треугольнике (см. рис. 2.11 а) заданы угол А, сторона с
и высота hb. Вычислить стороны a, b и углы B, C треугольника.
Вариант 2.29. В ромбе (см. рис. 2.11 б) заданы координаты вершин ха, уа,
хь, уь, хс, ус и xd, yd Вычислить стороны и диагонали ромба треугольника.
Вариант 2.30. В ромбе (см. рис. 2.11 б) заданы сторона а и угол А. Вычислить диагонали и угол B ромба.
В формулах для треугольников (рис. 2.11 а) используются следующие
обозначения: a, b , c – стороны треугольника; А, В, С – углы треугольника, противолежащие соответствующим сторонам; ha, hb, hc – высоты треугольника,
опущенные соответственно на стороны a, b и с; р, S – половина периметра и
площадь треугольника; r, R – радиусы вписанной и описанной окружностей.
В формулах и заданиях для ромба (рис. 2.11 б) используются следующие
обозначения: а – сторона ромба; А, В, С, D – углы ромба; d1 ,d2 – диагонали ромба; р, S – периметр и площадь ромба.
Приведем основные теоремы и формулы, необходимые для решения з адач с треугольниками:
a
sin A
b
sin B
c
– теорема синусов;
sin C
a2
b2 c 2 2 bc cos A – теорема косинусов;
S
0.5 absin C ; S
R
a
2 sin A
b
2 sin B
p( p a)( p b)( p c) – формула Герона;
c
; r
2 sin C
( p a )( p b)( p c)
p
34
; hb
a sin C
c sin A .
При расчете элементов трапеции кроме приведенных для треугольников
соотношений используются формулы:
A + B = C + D = 180 град; S = 0.5 (b + d) h.
Рис. 2.11. Обозначения элементов геометрических фигур
к вариантам лабораторной работы № 1: а – треугольник; б – ромб;
2.11. Контрольные вопросы
1. Перечислите состав программного проекта в среде C++ Builder.
2. Охарактеризуйте структуру головного файла проекта.
3. Охарактеризуйте структуру заголовочного файла формы.
4. Охарактеризуйте структуру файла реализации формы.
5. Охарактеризуйте области видимости переменных и функций в проекте.
6. Охарактеризуйте состав главного окна интегрированной среды разработки C++ Builder.
7. Охарактеризуйте состав и назначение панели инструментов управления
проектом.
8. Состав панели компонентов, назначение и вызов объектов с панели
компонентов и их размещение на форме.
9. Окно редактирования кода, его состав, назначение. и работа с ним.
10. Охарактеризуйте назначение и состав Инспектора объектов.
11. Свойства объекта и назначение их объектам. Обязательные свойства
объекта.
12. Задание свойств объектам при проектировании интерфейса.
13. Задание и изменение свойств объектов при написании программы.
14. События, их роль в программе на языке C++ Builder.
15. Функции обработки событий и их написание в программе.
16. Как записать передачу данных из текстового окна в программу.
17. Что такое комментарий, для чего он служит и как оформляется?
18. Что представляет собой оператор, какие функции выполняют операторы в программе?
35
3. ЛАБОРАТОРНАЯ РАБОТА № 2
Тема: «Разработка алгоритмов и программ с использованием управляющих операторов».
Цель работы: Ознакомится с технологией использования управляющих
операторов при разработке ветвлений в алгоритмах решения задач [1].
Задачи: В процессе выполнения работы студенты должны:
– изучить синтаксис операторов, организующих ветвящиеся процессы;
– научиться решать задачи ветвящейся структуры, составлять алгоритмы
и реализовывать программы;
– научиться использовать на практике отладочные средства среды ВС
при отладке программ с разветвлением;
– научиться анализировать иерархию условных операторов с точки
зрения оптимальности ее организации.
3.1. Теоретический материал
Рассмотрим пример. Даны переменные a и b ( a b ). Разработать алгоритм, позволяющий переменной max присвоить численное значение наибольшей переменной.
Математическая формулировка задачи:
max
a,
b
если a
b
в противном случае.
Анализ задачи показывает:
1. Существуют два возможных пути решения задачи:
max = a ( ветвь 1) и max = b ( ветвь 2).
2. Вопрос о том, численное значение какой из переменных, a или b, следует присвоить переменной max, может быть решен только после проверки одного из условий: a > b или a < b. Проверке может быть подвергнуто только одно из двух условий, поскольку они являются взаимоисключающими.
3. Проверка выбранного условия производится машиной в процессе выполнения программы, следовательно, разработчику программы результат этой
проверки заранее не известен. Поэтому в алгоритме нужно предусмотреть возможность вычислений по каждой из двух ветвей. Схема алгоритма может быть
представлена в виде (рис. 3.1).
Алгоритм состоит из линейной структуры, в которую вложен оператор проверки условия a > b и в зависимости от выполнения условия осуществляется выбор
по какой ветви продолжать вычисления.
Алгоритмы, в которых выбор процесса вычисления зависит от выполнения
каких-либо условий, относятся к алгоритмам с управляющими структурами.
Операторы условной передачи управления. К управляющим структурам
(в литературе встречается тождественное определение – структуры ветвления)
36
в языках программирования относятся операторы условной передачи управления и операторы безусловной передачи управления.
Пуск
Сложная линейная
структура
a, b
Да
Нет
Проверка заданного
условия
a>b
max : = b
max : = a
Вложенная ветвящаяся структураразветвление (глубина вложения
равна 1)
x, y
Останов
Рис. 3.1. Схема алгоритма
Оператор условной передачи управления в программе используют для
программирования ветвлений, т. е. таких вычислений, когда при определенных
условиях возникает необходимость выбора одного из возможных вариантов
вычислений.
В зависимости от количества проверяемых условий операторы условной
передачи управления делятся на простые и сложные.
Простыми называются операторы условной передачи управления с проверкой одного условия. Сложными – называются операторы с проверкой двух
(нескольких) условий.
Простые операторы условной передачи, в свою очередь, по сложности
проверяемого условия можно разделить на элементарные и составные.
Структура оператора условной передачи управления предполагает наличие в своем составе:
1. Условия L, которое записывается в виде логического выражения и может принимать значение true – истина или false – ложь.
37
2. Двух или нескольких альтернативных (взаимоисключающих) путей
решения задачи, называемых ветвями и представляющих собой типовые линейные структуры, причем математическая формулировка задачи каждой ветви ставит в соответствие вполне определенное значение условия L.
В качестве условия может выступать, например, операция сравнения двух
чисел. Если, допустим, условие записано в виде a > b, то результатом проверки
такого условия может быть либо утверждение «true» (истина), либо «false»
(ложь). При этом каждому результату должна соответствовать одна из двух
возможных ветвей.
Существует три разновидности ветвящейся структуры: ответвление, разветвление и условный оператор множественного выбора (переключение) (рис. 3.2).
L- истинно?
L- истинно?
Да
Да
Нет
Нет
P1
P1
P2
Р2
Р3
а
б
. ..
Да
P1
L (l1, l2, …ln)
P2
в
Нет
Pn
Рs
Рис. 3.2. Разновидности структуры оператора условной передачи
управления: а) ответвление; б) разветвление; в) переклю чение
38
Оператор ответвления. Для ответвления характерно наличие операций
только в одной из двух ветвей, а для разветвления – в обеих. Отличительной
особенностью переключения является то, что условие L может принимать несколько значений, в соответствии с каждым из которых будет выполняться о дна из нескольких ветвей P1, P2, ..., Pn.
При реализации структур оператора условной передачи управления на
языке С++ Builder используются операции отношения и эквивалентности двух
операндов (таб. 3.1). Они возвращают true – истина, если указанные соотношения операндов выполняются, и false – ложь, если соотношение не выполняется.
Таблица 3.1
Операции отношения и эквивалентности
Обозначе ние
==
!=
<
<=
>
>=
Операция
Равно
Не равно
Меньше чем
Меньше
или равно
Больше чем
Больше
или равно
Типы
операндов
Арифметический,
указатели
Арифметический,
указатели
Арифметический,
указатели
Арифметический,
указатели
Арифметический,
указатели
Арифметический,
указатели
Приме р
записи
I == Max
X != Y
X<Y
X <= Y
X>Y
X >= Y
Операнды должны быть совместимых типов, за исключением целых
и действительных типов, которые могут сравниваться друг с др угом.
Простой оператор условной передачи управления может быть з аписан в виде:
if (условие) оператор;
Скобки, обрамляющие условие, обязательны.
Например, в результате выполнения операторов
a = 10;
b =20;
if (b > a) c = b;
переменная с станет равной максимальному из чисел a и b, поскольку оператор c = b будет выполнен только при b > a.
Условием может быть арифметическое выражение, которое может быть
преобразовано в булев тип. Поскольку в С++ арифметическое (целое и действительное) значение может преобразовываться к булеву типу (любое ненулевое значение воспринимается как true, а нулевое – как false, то условие может иметь целый тип. Например :
int a, b, c, d;
…………
39
if ( a – b/c) d = c;
………….
В результате выполнения указанных операторов, если выражение
(a – b/c) будет иметь ненулевое значение (положительное или отрицательное), то переменой d будет присвоено значение c, если выражение
будет иметь нулевое значение, будет выполняться оператор, следующий
за условным оператором.
Внимание. Не рекомендуется в условии использовать арифметическое выражение с действительными числами, так как в результате ошибок округления
результат вычисления может не быть равен нулю, даже
когда чисто теоретически результат дает нуль.
Оператор разветвления. Форма
записи структуры разветвления
имеет вид:
if (условие) оператор1;
else оператор2;
Если условие возвращает true, то выполняется первый из указанных операторов, а в противном случае выполняется второй оператор.
Обратите внимание, что в конце первого оператора перед ключевым
словом else ставится точка с запятой.
Например:
if (j == 0)
ShowMessage (“Деление на нуль”);
else
Result = i/j;
Смысловое содержание приведенных операторов состоит в следующем:
если значение переменной j = 0, то выводится предупреждение, что в следующем операторе будет выполняться деление на нуль и выполнение этого опер атора пропускается, в противном случае выполняется оператор Result = i/j.
В качестве первого и второго оператора могут использоваться составные
операторы:
if (j == 0)
{
ShowMessage (“Деление на нуль”);
Result = 0;
}
else
{
Result = i/j;
B = Result*d;
}
Вложенные конструкции операторов. При написании программы могут
использоваться условные операторы, имеющие вложенные конструкции, когда
40
внутри одного условия проверяются другие условия. Схемы вложенных конструкций оператора условной передачи управления представлены на рис 3.3.
Рис. 3.3. Схемы вложенных условных операторов:
Запись оператора условной передачи управления с вложенными ко нструкциями имеет вид:
If ( условие1)
If ( условие2)
Оператор1;
Else оператор2;
Else оператор 3;
При написании операторов условной передачи управления с вложенными конструкциями необходимо проверять соответствие if и else. Компилятор
всегда считает, что else относится к последней из конструкций if, в которой не
было раздела else.
Например в конструкции:
if ( условие1)
if ( условие2)
Оператор1;
else оператор2;
else будет отнесено компилятором ко второй конструкции if , т. е. оператор2 будет выполняться, если первое условие истинно, а второе – ложно. Данная запись оператора тождественна следующей записи:
if ( условие1)
41
{
if ( условие2)
оператор1;
else оператор2;
}
Если необходимо отнести к первому, то выражение надо записать в явном
виде с помощью фигурных скобок:
if ( условие1)
{
if ( условие2) оператор1;
}
else оператор2;
Оператор с составным условием. При составлении конструкции оператора условной передачи управления могут использоваться составные условия, в
которых условия соединены логическими операциями
Основные логические операции
Обозначение
!
&&
||
Операции
Отрицание НЕ
Логическое И
Логическое ИЛИ
Таблица 3.2
Пример
!A
A && B
A||B
Оператор условной передачи управления с составной конструкцией условия записывается в виде:
if ((условие1 && условие2) | | условие3) оператор1;
else оператор2;
В данном операторе условной передачи управления при выполнении условия1 и условия2 или условия3 выполняется оператор1, в противном случае оператор2.
Имеется ещё одна форма записи оператора условной передачи
управления – условная операция. Синтаксис ее записи имеет вид:
условие ? оператор1 : оператор2;
Результатом выполнения условной операции является выполнение
оператора1, если условие истинно, либо оператор2, если условие ложно.
Например, оператор:
max = ( x > y) ? х : у;
присваивает переменной max наибольшее из значений переменных х и у.
Оператор множественного выбора (переключатель). Оператор множественного выбора ( иногда называют переключателем) позволяет провести анализ значения некоторого выражения и в зависимости от его значения выполнить те или иные действия. В общем случае формат записи оператора switch
следующий:
switch (выражение выбора)
{
42
case значение 1: оператор 1
break;
case значение 2: оператор 2
break;
…………………………………..
case значение k: оператор k
break;
[ default: оператор k+1]
}
где оператор default не является обязательным.
В этой конструкции выражение выбора (условия, указанного в круглых
скобках) должно иметь порядковый тип – целый, перечисляемый и т. д. Поэтому, например, нельзя использовать выражения, возвращающие действительные числа или строки.
Значения, указываемые в метках case, должны быть константными выражениями, соответствующие возможным значениям выбора. После значения
ставится двоеточие «:», а затем пишется оператор (можно писать составной
оператор), который должен выполняться, если выражение приняло указанное
в метке значение.
При выполнении оператора switch реализуется последовательность операторов, соответствующая текущему значению выражения выбора. Если значение
выбора совпало со значением, указанным в метке, то выполняется оператор, записанный после этой метки, после чего, если не принять соответствующих мер,
будут выполняться все последующие операторы остальных меток. Поскольку
это обычно нежелательно, то, как правило, после оператора, который должен
выполняться, записывают оператор:
break;
Если это значение не совпадает ни с одним из перечисленных значений и
оператор default присутствует, выполняется следующий за ним оператор. Если
не нашлось соответствующего значения выражения выбора и оператор default
отсутствует, то действие оператора switch аналогично пустому оператору.
Оператор безусловной передачи управления. Оператор безусловной передачи управления предназначен для нарушения естественного порядка выпо лнения операторов в программе и передачи управления в произвольную точку
кода, помеченную меткой по усмотрению программиста.
Структура оператора:
goto m;
где goto – ключевое слово (идти к); m– метка оператора, которому передаётся управление.
Оператор, на который необходимо передать управление помечается меткой (m:), после которой ставится двоеточие.
Использование укороченного оператора условной передачи управления
со структурой if (B) goto m допускается, но не поощряется правилами структур-
43
ного программирования, так как создаёт достаточно сложную структуру ветвления с использованием двух меток.
Отладку программ с ветвлениями удобно выполнять с помощью отладочных средств системы С, которые позволяют остановить выполнение программы в любой (критической) точке и с помощью пункта меню Debug –>
Evaluate просмотреть значение любой известной в этой точке переменной либо выражения, определяющих направление разветвления. Установить точку
наблюдения можно с помощью курсора или пункта меню Debug –> Toggle
breakpoint. Достижение точки наблюдения в первом случае осуществляется с
помощью пункта меню Run –> go to cursor, а во втором случае с помощью
пункта Run –> Run. Достигнуть точки наблюдения можно также с помощью
пошагового выполнения программы (клавиши [F7] или [F8], первая из которых
при трассировке программы сканирует все вызываемые программой функции,
а вторая не делает этого, выполняя всю вызываемую функцию за один шаг).
3.2. Примеры решения задач
Проект программного продукта для решения двух следующих задач разрабатывается на языке C++ Bilder c применением стандартных объектов Label,
Edit, Button и RadioButton.
Рассмотрим следующие две задачи.
Пример 3.1. Разработать алгоритм интерфейс пользователя и программу
решения задачи ветвящейся структуры с разветвлением.
Даны переменные a и b ( a b ). Разработать программу, позволяющую
определить максимальное или минимальное из этих двух чисел и вывести на
форму по желанию пользователя максимальное либо минимальное число:
a, если a < b
max =
b в противном случае;
a,
если a < b
min =
b в противном случае.
При разработке интерфейса необходимо предоставить возможность пользователю изменять шрифт и цвет шрифта.
Анализ задачи и разработка алгоритма:
1. Существуют два возможных пути решения задачи:
max = a (ветвь 1) и max = b (ветвь 2).
2. Вопрос о том, численное значение какой из переменных a или b, следует присвоить переменной max, может быть решен только после проверки одного из условий: a > b или a < b. Проверке может быть подвергнуто только одно
из двух условий, поскольку они являются взаимоисключающими.
Так как необходимо найти максимальное либо минимальное число, то из
результата проверки условий следует: если число a имеет максимальное значе44
ние, то число b имеет минимальное значение и наоборот. Следовательно, для
решения поставленной задачи достаточно проверки только двух указанных
условий.
3. Проверка выбранного условия производится машиной в процессе выполнения программы, следовательно, разработчику программы результат этой
проверки заранее не известен. Поэтому в алгоритме нужно предусмотреть возможность вычислений по каждой из двух ветвей.
4. Для организации вывода максимального либо минимального числа
можно использовать стандартные объекты панели компонентов: RadioButton
(радиокнопки), RadioGroup (группы радиокнопок) и др.
Алгоритм состоит из линейной структуры, в которую вложена типовая
ветвящаяся структура-разветвление (рис. 3.4).
Начало
int a, b, c, d;
Ввод a, b;
a >= b
да
нет
c = a;
c = b;
d = b;
d = a;
Управление
выводом
max c;
min d;
Останов
Рис. 3.4. Схема алгоритма решения задачи
45
Разработка интерфейса пользователя. Запустим C++ Bilder и создадим
новый проект. На открывшуюся форму разместим объекты.
Для решения задачи определения максимального из двух чисел Label1,
Label2, Label3, Label4, Label5, Edit1, Edit2, RadioButton1, RadioButton2. Для
управления переключателями используется свойство Checked. Которое принимает значение true, если переключатель отмечен, и false, если переключатель не
отмечен. В качестве исходного состояния переключателей установим для одного из них значение свойства Checked, равное true, для другого – false.
Разместив на форме указанные объекты, сделаем соответствующие
надписи, как показано на рис. 3.5.
Для выбора шрифта и цвета шрифта объекты, RadioGroup1 и RadioGroup2
в каждом из которых разместим по три переключателя, работающих соглас ованно. Управление переключателями осуществляется через свойство ItemIndex,
которое в зависимости от числа переключателей может принимать значение по
числу переключателей. В данном примере используются три переключателя,
поэтому свойство ItemIndex для включенного переключателя может принимать
значение {1, 2, 3} соответственно.
Написание кода программы. Написание кода программы будем производить в следующей последовательности:
1. Напишем код функции обработки события Click для кнопки Выход.
2. Напишем код функции обработки события Click для кнопки Найти, включив в неё операторы выбора варианта решения задачи в зависимости от отмеченного
переключателя RadioButton.
3. Напишем код функции обработки события Click для объекта RadioGroup1
и RadioGroup2. Листинг программы приведен ниже.
Рис. 3.5. Форма с интерфейсом пользователя
46
Листинг программы к примеру 3.1
void __fastcall TForm1::Button1Click(TObject *Sender)
{
.//поиск максимального и минимального числа
int a,b,c,d;
a = StrToInt(Edit1->Text);
b = StrToInt(Edit2->Text);
if (a >= b)
{
c = a;
d = b;
}
else
{ c = b;
d = a;
}
// выбор выводимого числа в метку в зависимости от включенной радиокнопки
if (RadioButton1->Checked)
{
Label5->Caption = "";
Label3->Caption = "max";
Label5->Caption = IntToStr(c);
}
else
{Label3->Caption ="min";
Label5->Caption = IntToStr(d);
}
}
//--------------------------------------------------------------------------void __fastcall TForm1::RadioGroup1Click(TObject *Sender)
{
//изменения шрифта текста в метке Label6
if (RadioGroup1->ItemIndex == 0) Label6 -> Font->Name = "Times New
Roman";
if (RadioGroup1->ItemIndex == 1) Label6 -> Font->Name = "Arial";
if (RadioGroup1->ItemIndex == 2) Label6 -> Font->Name = "Tahoma";
}
//--------------------------------------------------------------------------void __fastcall TForm1::RadioGroup2Click(TObject *Sender)
{
// изменение цвета текста в метке Label6
if (RadioGroup2->ItemIndex == 0) Label6 -> Font->Color = clRed;
if (RadioGroup2->ItemIndex == 1) Label6 -> Font->Color = clBlue;
47
if (RadioGroup2->ItemIndex == 2) Label6 -> Font->Color = clBlack;
if (RadioGroup2->ItemIndex == 3) Label6 -> Font->Color = clGreen;
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button2Click(TObject *Sender)
{
Form1->Close();
}
//-----------------------------------------------------------------------Откомпилируйте программу и проверьте её работоспособность.
Пример 3.2. Разработать алгоритм, интерфейс пользователя и программу
для решения задачи с глубиной вложения ветвящейся структуры, равной двум, с
использованием логических выражений.
Составить программу решения следующей задачи:
z
a * x,
еcли
a
2и 0
3
a2 * x ,
если
a 3 или 4
5
a3 * x ,
x
4
x
16
в остальных случаях
При разработке интерфейса предусмотреть ввод исходных данных и вывод результата расчетов на форму.
Внешняя спецификация задачи:
a – положительное целое;
x – положительное целое;
Z – вещественное.
Выбор метода решения. При решении задачи используются стандартные
математические функции: возведение в степени и извлечение корней 2, 3 и 5
степени.
Следовательно, нам требуется подключить файлы с математическими и
тригонометрическими функциями math.h и Math.hpp. в заголовочный файл модуля формы как показано в лабораторной работе 1.
В отличие от предыдущего примера, где в качестве условий в операторах if
использовались выражения отношения, здесь условия представляют собой более
сложные логические выражения, содержащие логические операции «и» и «или».
Разработка алгоритма. Схема алгоритма на рис. 3.6.
Разработка интерфейса пользователя. Создадим проект и на форме разместим метки и текстовые окна для информирования пользователя и ввода исходных данных. Вывод результатов расчета будем осуществлять в окно редактирования списков Memo, которое разместим на форме.
Для вывода строки данных в окно Memo используется выражение:
Memo1->Lines->Add(FloatToStr(z));
Вид формы проекта после размещения указанных объектов показан на
рис. 3.7.
48
Начало
x, a
a = 2 и x=1
Да
Да
Нет
a = 3 или x=2
Нет
z:
=
5
a3 x
a x
z:
3
a2 x
=
a x
z:
=
z
Останов
Рис 3.6. Схема алгоритма решения задачи
Рис.3.7. Вид формы для примера 3.2
49
a x
a x
Написание кода программы. Выделим командную кнопку Вычислить, в
Инспекторе объектов перейдем на вкладку Events, выделим событие Click и в
окне редактора кодов в секции для события Click командной кнопки напишем
код обработки события, представленный ниже.
Листинг программы к примеру 3.2
void __fastcall TForm1::Button1Click(TObject *Sender)
{
unsigned short a,x;
float z,z1,b;
const float b1 =1;
b = b1 / 3;
a = StrToInt(Edit1->Text);
x = StrToFloat(Edit2->Text);
if(a==2 && (x>0 && x<=4))
{
z =sqrt(float (a*x));
//вывод результата в окно Memo
Memo1->Lines->Add(FloatToStr(z));
}
else {if (a==3 && (x>4 && x<=16))
{
z1 =float (a*a*x);
z = pow(z1,b); .// функция возведения в степень (Z1)b
Memo1->Lines->Add(FloatToStr(z));
}
else
{
b =b1/5;
z1 =float (a*a*a*x);
z = pow(z1,b);
Memo1->Lines->Add(FloatToStr(z));
}
}
}
Откомпилируем программу, введем исходные данные и протестируем
программу.
Пример 3.3. Пример разработки программы, использующей оператор
множественного выбора.
Разработать программу, позволяющую определить результаты тестирования. В зависимости от количества правильных ответов и нтерфейс
программы должен позволять вводить число правильных ответов и выв одить результат тестирования с комментариями.
Внешняя спецификация программы. Общее число заданных вопросов –
50
положительное целое.
Число правильных ответов – положительное целое.
Оценка за ответ, соответствующая числу правильных ответов – положительное целое.
Комментарии к оценке – строковый тип. В качестве комментариев результатов будем использовать следующие строковые выражения:
"Поздравляем, вы получили 5";
"Хорошо, у вас 4";
"У вас всего лишь 3";
"Плохо, у вас 2";
"Ужасно! Учите лучше!";
Выбор метода решения. Решение задачи может быть описано выражением:
5, если x>=a;
4, если a>x>=b:
3, если b>x>=c:
Y=
2 если c> x>=d;.
1, если x<d.
Алгоритм решения задачи. Возможный вариант – схема алгоритма решения задачи с использованием оператора множественного выбора – представлен
на рис. 3.8.
Начало
n, ,x
L(x,a,b,c,d)
(((ax,a,b,c,d
)
5
3
4
2
Вывод (5,4,3,2)
Конец
Рис. 3.8. Схема алгоритма множественного выбора
51
Разработка интерфейса программы. Создадим проект и на форме разместим
метки и текстовые окна для информирования пользователя, ввода исходных данных и вывода результата тестирования, как показано на рис. 3.9.
Написание кода программы. Код программы будем писать для функции
обработчика события Click командной кнопки Оценка. Для досрочного прекращения сравнения условий используем оператор break, а в конце используем
оператор default. Листинг программы приведен ниже.
Рис. 3.9. Интерфейс программы Результаты тестирования
Листинг программы к примеру 3.3
void __fastcall TForm1::Button1Click(TObject *Sender)
{
const unsigned int A=8, B=6, C=5, D=4;
unsigned int grade ;
grade =StrToInt( Edit1->Text);
switch (grade)
{ case 10:
Label1->Caption= "Поздравляем, вы получили 5" ;
break;
case 9:
Label1->Caption= "Поздравляем, вы получили 5" ;
break;
case A:
Label1->Caption= "Поздравляем, вы получили 5" ;
break;
case B:
Label1->Caption ="Хорошо, у вас 4";
break;
52
case C:
Label1->Caption ="У вас всего лишь 3";
break;
case 'D':
Label1->Caption= "Плохо, у вас 2" ;
break;
default:
Label1->Caption= "Ужасно! Учите лучше!";
}
}
Откомпилируем программу, введем исходные данные и протестируем
программу.
3.3. Задания для лабораторной работы № 2
Разработать алгоритм, интерфейс пользователя и написать программу
решения указанного варианта задания. При разработке интерфейса предусмо треть размещение на форме информации для пользователя, ввод исходных данных и вывод результатов вычисления в текстовые окна и метки.
Вариант 3.1. Разработать алгоритм, интерфейс пользователя и программу
вычисления величины z по формуле:
x3/y, если y !=0;
Z=
“ делитель равен 0”,если y=0.
Вариант 3.2. Разработать алгоритм, интерфейс пользователя и программу
вычисления величины z по формуле:
z = x3/y, где y = sin (n*x + 0,5).
Вариант 3.3. Разработать алгоритм, интерфейс пользователя и программу
вычисления величины z по формуле:
sin (x) , если x <= a;
Z = cos (x), если a < x < b;
tg (x), если x >= b.
Вариант 3.4. Разработать алгоритм, интерфейс пользователя и программу
упорядочивания трех чисел: a, b, c.
Вариант 3.5. Разработать алгоритм, интерфейс пользователя и программу
вычисления величины y по формуле:
ln (x), если x >= 1
1 , если x = 0;
y=
ex, если x <= –1.
Вариант 3.6. Разработать алгоритм, интерфейс пользователя и программу,
позволяющую найти квадрат наибольшего из двух чисел a и b. Вывести признак
N = 1, если наибольшим является a и признак N = 2 в противном случае.
Вариант 3.7. Разработать алгоритм, интерфейс пользователя и программу, позволяющую определить, можно ли построить треугольник из трех отрез53
ков длиной a и b, c, вывести результат.
Вариант 3.8. Разработать алгоритм, интерфейс пользователя и программу,
позволяющую определить, совпадает ли конец отрезка с полярными координатами R и φ с точкой с координатами x1, y1.
Вариант 3.9. Разработать алгоритм, интерфейс пользователя и программу,
позволяющую вычислить момент инерции различных типов профилей, (используйте оператор множественного выбора).
При k = 1 I = (B * H3) /12;
При k = 2 I = (B * H – b * h)3 / 12;
При k = 3 I = (B * H3 – b * h3) / 12;
Вариант 3.10. Разработать алгоритм, интерфейс пользователя и программу, позволяющую вычислить площадь одной из геометрических фигур по выбору пользователя:
– треугольника – по заданным основанию и высоте;
– прямоугольника – по заданным длине и ширине;
– трапеции – по заданным основаниям и высоте;
– круга – по заданному радиусу.
При разработке интерфейса для предоставления права выбора использ овать переключатели.
Вариант 3.11. На каждый день недели запланированы определенные работы. Разработать алгоритм, интерфейс пользователя и программу, позволя ющую по введенному признаку дня недели вывести запланированное на этот
день задание.
Вариант 3.12. Известно расписание занятий на день. Разработать алгоритм, интерфейс пользователя и программу, позволяющую по введенной паре
часовых занятий вывести наименование занятий и номер аудитории.
Вариант 3.13. Разработать алгоритм, интерфейс пользователя и программу, позволяющую вычислить значение величины z по формуле:
a + b, при a < b
Z=
a – b, при b > a.
Вариант 3.14. Разработать алгоритм, интерфейс пользователя и программу, позволяющую вычислить значение величины z по формуле:
a + b – c, при a < b и c < a + b;
Z=
a – b + c, при b > a и c > a – b.
Вариант 3.15. Разработать алгоритм, интерфейс пользователя и программу, позволяющую вычислить значение величины z по формуле:
arcsin (x), при –1 < x < 1;
Z=
arctg (x), при b –1 > x > 1.
Вариант 3.16. Разработать алгоритм, интерфейс пользователя и программу, позволяющую вычислить значение величины z по формуле:
a + b + c, при a > 0, b < 0 и c > a + b;
Z=
a – b – c, при a > b и с < a – b или c < 0.
54
Вариант 3.17. Разработать алгоритм, интерфейс пользователя и программу, позволяющую вычислить значение величины z по формуле:
Z=
|x| при x <= 1;
x2 при 1 < |x| <= 2;
4 в других случаях.
Вариант 3.18. Разработать алгоритм, интерфейс пользователя и программу,
позволяющую вычислить значение величины y по формуле. Для выбора варианта
расчета использовать переключатели.
sin (x);
cos (x);
y=
ex
Вариант 3.19. Дана окружность радиуса R с центром в точке с координатами x0, y0. Разработать алгоритм, интерфейс пользователя и программу, позволяющую определить, лежит ли точка с координатами x1, y1 внутри окружности.
Вариант 3.20. Разработать алгоритм, интерфейс пользователя и программу, позволяющую вычислить значение величины y по формуле:
bx – lg (bx) при bx < 1;
1 при bx = 1;
y=
e-bx + lg (bx).
Вариант 3.21. Дан квадрат с центром в точке с координатами x0, y0 и
длиной стороны, равной a. Стороны параллельны осям 0x и 0y. Разработать алгоритм, интерфейс пользователя и программу, определить, находится ли точка
с заданными координатами x, y внутри прямоугольника.
Вариант 3.22. Разработать алгоритм, интерфейс пользователя и программу, позволяющую вычислить значение величины y по выбранной пользователем формуле:
y=
1,5 * cos 2 x;
1,8 * a * x;
(x – 2)2 + 6;
3 * tg (x).
Вариант 3.23. Дано кольцо с центром в начале координат. Радиус внешней окружности R и внутренней r, Разработать алгоритм, интерфейс пользователя и программу, позволяющую определить находится ли произвольно заданная точка с координатами x, y в кольце либо внутри кольца.
Вариант 3.24. Генератор случайных чисел выдает целое число в диапазоне от 1 до 100. Разработать алгоритм, интерфейс пользователя и программу,
позволяющую определить, является это число четным или нечетным.
Вариант 3.25. Генератор случайных чисел выдает целое число в диапазоне от 1 до 100. Разработать интерфейс пользователя, алгоритм и программу,
позволяющую определить, является это число четным, или делится на 3, или не
делится ни на 2, ни на 3.
55
Вариант 3.26. Разработать алгоритм, интерфейс пользователя и программу, позволяющую вычислить значение величины y по формуле:
lg (y – x) при x < y;
y=
sin2 √|y – x| при x >= y.
Вариант 3.27. Разработать алгоритм, интерфейс пользователя и программу, которая вычисляет частное двух чисел. Программа должна проверять пр авильность введенных пользователем данных и, если они неверные (делитель
равен нулю), выдавать сообщение об ошибке. «Вы ошиблись. Делитель не должен быть равен нулю».
Вариант 3.28. Разработать алгоритм, интерфейс пользователя и программу вычисления площади кольца. Программа должна проверять правильность
исходных данных. «Ошибка! Радиус отверстия не может быть больше радиуса
кольца».
Вариант 3.29. Разработать алгоритм, интерфейс пользователя и программу, позволяющую вычислить значение величины y по выбранной пользователем формуле:
a * sin2 (x) при a >= 0 и 0 < x < π;
a * lg x + √(x + 1) при a < 0 и x > π.
Y=
Вариант 3.30. Дни недели пронумерованы от 1 до 7. На каждый день записано какое-либо задание. Разработать алгоритм, интерфейс пользователя и
программу, позволяющую по введенному номеру дня недели вывести предписанное задание.
Вариант 3.31. В прямоугольной системе координат из начала координат
проведена прямая под углом к оси ОХ , равная φ. Координаты точки А (x > 0, y
> 0). Разработать алгоритм, интерфейс пользователя и программу, позволяющую определить, выше или ниже линии находится точка А.
3.4. Контрольные вопросы
1. Какие функции выполняет условный оператор?
2. Что такое полный и неполный условный оператор? В чем разница между ними? Нарисуйте их схемы.
3. Что такое ветвь?
4. Почему в программе необходимо предусматривать вычисления по всем
возможным ветвям?
5. Какие вычислительные процессы относятся к ветвящимся?
6. Что такое вложенный условный оператор? Как определяется соответствие между операторами if и else во вложенных условных операторах?
7. Что такое условная операция и чем она отличается от условного оператора?
8. С помощью каких операций формируется условие в условном операторе и условной операции?
9. Что такое составной оператор и когда его следует применять внутри
56
условного оператора?
10. Из каких компонент состоит оператор множественного ветвления?
11. Дайте характеристику служебного слова default. Как работает оператор switch при отсутствии оператора default.
12. Как выполняется отладка программ, содержащих ветвления вычислительного процесса?
13. Для чего нужны операторы передачи управления?
14. Приведите структуру оператора перехода.
15. Что представляет собой метка, для чего она используется?
16. Можно ли передать управление одной из альтернатив при помощи
оператора goto?
17. Для чего выполняются условно-линейные схемы алгоритмов?
18. Почему разные условно-линейные схемы требуют различных условных операторов?
19. Какие логические операции используются в С++ Builder?
20. Какие объекты в языке С++ Builder могут использоваться для организации выбора пользователем альтернативного варианта?
21. Как записывается код обращения к объектам выбора альтернативных
вариантов?
22. Как можно вывести в интерфейс информацию об осуществленном
выборе?
23. Дайте характеристику свойств и методов объекта RadioButton.
24. Дайте характеристику свойств и методов объекта RadioGroup.
25. Дайте характеристику свойств и методов объекта GroupBox.
4. ЛАБОРАТОРНАЯ РАБОТА № 3
Тема: «Разработка программ с использованием циклических структур».
Цель работы: Изучить технологию решения задач с использованием циклических алгоритмов [1].
Задачи:
– научиться разрабатывать алгоритмы циклических структур;
– изучить синтаксис описания различных вариантов циклических
структур на языке С++ Builder;
– закрепить навыки разработки и отладки программ с циклическими
структурами.
4.1. Теоретические сведения
Циклическим называется процесс многократного повторения некоторого
участка вычислений при изменении хотя бы одной из входящих в него величин.
Сформулируем основные определения.
Цикл – повторяющийся участок вычисления.
57
Параметр цикла – входная величина, изменяющая своё значение от цикла к циклу.
Тело цикла – совокупность действий, осуществляемых в цикле.
Закон изменения параметра цикла – зависимость, связывающая текущее и предыдущее значения параметра цикла.
Условие повторения цикла – зависимость, предписывающая повторение
цикла либо выход из него.
Все циклические структуры по способу определения количества повторений
(N) разделяются на арифметические и итерационные.
Арифметической называется циклическая структура, число повторений
в которой может быть определено заранее, т. е. не зависит от результатов счёта
в теле цикла. Такая циклическая структура называется циклом со счетчиком
или цикл «for».
Итерационной именуется циклическая структура, число повторений в
которой зависит от результатов вычислений в теле цикла и не может быть
определено заранее. К таким циклическим структурам относятся:
– цикл с предусловием, часто называемым циклом «ПОКА» или циклом
«while»;
– цикл с постусловием, часто называемым циклом «ДО» или циклом
«do».
Независимо от того, к какому классу относится вычислительный процесс,
каждый из них содержит обязательные элементы: вход в цикл (формирование
начального значения параметра цикла); вычисления в теле цикла; выход из
цикла.
1. Цикл for. Обеспечивает циклическое повторение некоторого оператора заданное число раз. Повторение цикла определяется некоторой управляющей переменной (счетчиком), которая изменяется при каждом выполнения тела цикла. Повторение завершается, когда управляющая переменная
достигает заданного значения. Синтаксис структуры for:
for ( выражение1; выражение2; выражение3)
{
оператор;
}
где выражение1 задает начальное значение переменной, управляющей циклом,
выражение2 является условием продолжения цикла, а выражение3 изменяет
управляющую переменную.
Структура for работает следующим образом. Сначала выполняется выражение1 (оно может состоять из ряда выражений, разделенных запятой т. е.
может использоваться операция последования), которая определяет значения
любых переменных перед началом цикла. Затем проверяется выражение2 –
условие завершения цикла. Если условие истинно (возвращает true – ненулевое
значение), то выполняется тело цикла, оператор, записанный в теле цикла. После завершения тела цикла выполняется выражение3, определяющее изменение
переменной цикла. Затем опять проверяется условие, записанное как выражение2, и при истинности этого условия выполнение тела цикла продолжается.
58
Как только в каком-нибудь цикле выражение2 вернет false (нулевое значение), цикл прерывается и управление передается оператору, расположенному
следом за структурой for.
Пример 4.1. Определим максимальное значение и сумму 100 случайных
чисел в диапазоне от 1 до100.
начало
Ввод исходных
данных: n
I = 1…n
Генератор случайного числа
Вывод n чисел
I = 1…n
Суммирование чисел
Поиск максимального
числа
Вывод суммы и максимального
числа
Конец
Рис. 4.1. Схема алгоритма использования цикла for
59
Внешняя спецификация программы.
Исходные данные:
100 целых чисел, выбранных случайным образом в диапазоне от 1 до 100:
Выходные данные:
Максимальное значение целого числа.
Сумма всех чисел.
Выбор метода решения задачи. Выбор случайных чисел осуществляется с
помощью генератора случайных чисел. Выбранные числа выводятся и сохр аняются. Далее осуществляется последовательное сравнение чисел, поиск максимального числа и суммирование всех чисел.
Схема алгоритма приведена на рис. 4.1.
Разработка интерфейса пользователя. Для ввода количества чисел будем
использовать текстовое окно Edit. Для вывода результатов будем использовать
текстовые окна Edit. Для вывода дополнительной информации используем метки Label.
Для генерации случайного числа будем использовать стандартную функцию random(). Вывод сгенерированных чисел будем осуществлять в объект
ListBox, его свойство Items и метод Add(k) добавить элемент в список. Синтаксис выражения:
ListBox1->Items->Add(k).
Для считывания из ListBox элемента используем свойство Items и метод
Strings[i] – считать строку. Синтаксис выражения:
ListBox1-> Items->Strings[i].
Для управления программой используем три командные кнопки: Генерировать числа, Вычислить и EXIT.
Разработанный интерфейс представлен на рис. 4.2.
Рис. 4.2. Интерфейс программы определения суммы n чисел
и нахождения максимального числа
60
Разработка кода программы. Программа содержит три функции обрабо тки событий Click трех командных кнопок: Генерировать числа, Вычислить и
Exit листинг программы приводится ниже. Программа содержит два цикла. В
первом цикле генерируется n чисел и они выводятся в ListBox1. Во втором цикле осуществляется поиск максимального числа и суммирование чисел.
Листинг программы генерации n чисел, нахождения их суммы и максимального числа.
void __fastcall TForm1::Button3Click(TObject *Sender)
{
Form1->Close();
}
//--------------------------------------------------------------------------// генерация чисел
void __fastcall TForm1::Button1Click(TObject *Sender)
{
randomize();
int k,i,j;
int N =100,m =100;
N=100;
m=100;
k=0;
i=0;
j=0;
for (i=0;i<m;i++)
{
k= random(N);
j=j+1;
ListBox1->Items->Add(k);
}
}
//--------------------------------------------------------------------------//поиск максимального числа и суммирования чисел
void __fastcall TForm1::Button2Click(TObject *Sender)
{
int max, sum;
max=0;
sum=0;
m= 100;
for (i=0;i<m;i++)
{
k=0;
k = StrToInt(ListBox1-> Items->Strings[i]);
if(k > max) max = k;
61
sum = sum+k;
}
Label4->Caption=max;
Label6->Caption=sum;
}
Цикл с предусловием:
Оператор while используется для организации многократного выполнения тела цикла, пока выполняется некоторое условие. Синтаксис структуры
оператора while:
while (условие) тело цикла.
Здесь условие представляет собой любое выражение, принимающее
значение 0 (ложь) или не 0 (истина), тело цикла – простой (или составной)
оператор либо блок.
Рис. 4.3. Схемы выполнения операторов циклов
а – оператор for; б – оператор while; в – оператор do….while
Цикл с постусловием. Структура do…while используется для организации
многократного выполнения оператора или совокупности операторов (блока),
составляющих тело цикла, до тех пор пока не окажется нарушенным некоторое
условие. Синтаксис цикла do….while:
do тело цикла while (условие)
Структура работает следующим образом. Вначале выполняется тело
цикла, затем вычисляется заданное условие, которое должно возвращать р езультат, если условие выполняется (true), то повторяется выполнение тела
цикла и после этого снова проверяется условие. Если проверяемое условие
вернет false, то выполнение цикла прерывается и управление передается
следующему за структурой do…while оператору. Поскольку проверка условия осуществляется после выполнения тела цикла, то цикл будет заведомо
выполнен хотя бы один раз, даже если условие сразу не выполняется.
Для досрочного выхода из цикла может использоваться оператор break.
Блок-схема цикла с постусловием представлена на рис. 4.3 в.
62
Вначале вычисляется условие. Если оно оказывается истинным, то выполняется тело цикла; в противном случае управление передается оператору,
следующему за телом цикла. Поскольку проверка условия осуществляется перед выполнением оператора тела цикла, то, если условие сразу ложно, оператор
не будет выполнен ни одного раза.
Иногда может потребоваться досрочный выход из цикла, например при выполнении некоторого условия в теле цикла. Для этого может быть использован
оператор break, прерывающий цикл. Блок-схема цикла с предусловием представлена на рис. 4.3 б.
Пример 4.2. Решение задачи с использованием циклов while и do….while
для вычисления суммы членов числового ряда.
Начало
Начало
Исходные
данные X,
E
Исходные
данные X, E
,
,
.
A<
,
,
.
A<
an+1 < E
Вычисление
an+1 члена
Вычисление
a n+1 члена
Вычисление
суммы s=s+an+1
Вычисление
суммы
an+1 < E
s=s+an+1
Вывод s и n
Вывод s и
n
Конец
Конец
Цикл do…while
Цикл while
Рис. 4.4.Схема алгоритма нахождения суммы членов числового ряда
63
Необходимо разработать алгоритм интерфейс и программу, позволяющую найти сумму членов бесконечного ряда с точностью до члена ряда, меньшего , и число слагаемых в сумме :
x2 x3
xn
z 1 x
...
...
2! 3!
n!
Выбор метода решения задачи.
При нахождении суммы такого ряда не следует вычислять отдельно каждый элемент. Достаточно установить зависимость, по которой из предыдущего
элемента ряда образуется следующий. Обозначим через an n-й член ряда, тогда
an+1 = an x / (n + 1), a 0 = 1. Такой подход позволяет сократить количество вычислительных операций и уменьшить время счета. Сумму будем накапливать в
переменной S, которую предварительно необходимо обнулить. Условие окончания цикла an
. Число повторных вычислений в теле цикла равно числу
слагаемых в сумме. На рис. 4.4 представлены схемы алгоритмов решения поставленной задачи с использованием циклов while и do…while.
Разработка интерфейса пользователя. Для ввода исходных данных и вывода результатов расчета будем использовать текстовые окна Edit. Для вывода
дополнительной информации используем метки Label. Для управления программой разместим три командные кнопки: Вычислить while, Вычислить
do…while и EXIT.
Разработанный вариант интерфейса представлен на рис. 4.5.
Рис. 4.5. Интерфейс программы вычисления суммы членов
числового ряда с заданной точностью
64
Разработка кода программы. В данной программе операторы циклов вычисления суммы членов ряда размещены в двух функциях обработки событий
двух кнопок. Для того, чтобы переменные были доступны в этих двух функциях, они должны быть объявлены вне этих функций, как показано в листинге
программы, приведенной ниже.
Листинг программы вычисления суммы членов числового ряда
//--------------------------------------------------------------------------void __fastcall TForm1::Button1Click(TObject *Sender)
{
Form1->Close();
}
//--------------------------------------------------------------------------//объявление переменных, видимость которых в пределах
//модуля, производится перед функцией обработки события.
int i;
float a1,a2,x,s,d, d1 ;
void __fastcall TForm1::Button2Click(TObject *Sender)
{
x = StrToFloat(Edit1->Text);
d = StrToFloat(Edit2->Text);
s=1;
i=1;
d1=1;
a1 = 1;
a2 = 0;
while(d1 >= d) //цикл while
{
i = i+1;
a2=a1*x/i;
s = s+a2;
d1 = a2;
}
Edit3->Text = s;
Edit4->Text = i;
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button3Click(TObject *Sender)
{
Do //цикл do
{
65
i = i+1;
a2=a1*x/i;
s = s+a2;
d1 = a2;
}
while(d1 >= d);
Edit5->Text = s;
Edit6->Text = i;
}
Откомпилируем программу и, введя исходные данные, проверим ее р аботоспособность. Из анализа результатов расчета (рис. 4.5) видно, что при решении задачи с использованием цикла while количество слагаемых на единицу
больше, чем при использовании цикла do…while.
4.2. Задания для лабораторной работы № 3
Вариант 4.1. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить и вывести на печать сумму К членов
числового ряда:
K
k2 k 1
S
( 1) k 1
.
xk
k 1
Вариант 4.2. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить и вывести на печать сумму членов числового ряда с точностью E.
k
K
2
S
.
2
1
k 0 k
Вариант 4.3. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить и вывести на печать произведение К
членов числового ряда:
( 1) k * [k 2 k 1]
;
1 * 2 * 3 * ... * k
k0
K
P
k
целое K ввести с клавиатуры.
Вариант 4.4. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить и вывести на печать сумму членов числового ряда:
k
K
x
S
при x 1
2
2
k 0 k
с точностью
ak
S
0,001.
Вариант 4.5. Разработать алгоритм, интерфейс пользователя и написать
66
код программы, позволяющей вычислить и вывести на печать произведение членов числового ряда:
K
sin( kx)
P
1)
k 1 1 * 3 * 5 * ...* ( 2k
с точностью ak 0,01.
Вариант 4.6. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить и вывести на печать сумму К членов
числового ряда:
K
k2 k 1
S
( 1) k 4
.
k k 10
k 0
Вариант 4.7. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить и вывести на печать сумму членов числового ряда:
K
x 2k 1
k
S
1
при x 1 .
(
2
k
1
)
!
k 1
ak
с точностью S 0,001.
Вариант 4.8. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить и вывести на печать произведение членов числового ряда:
K
k 1
P
( 1) k 3
x k при x 0,1 .
k k 1
k 0
с точностью ak 0,01.
Вариант 4.9. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить и вывести на печать сумму членов числового ряда:
K
S
1
k 1
k 1
x 2k 1
(2k 1) !
при x
1.
с точностью ak 0,0001.
Вариант 4.10. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить и вывести на печать произведение К
членов числового ряда:
K
k 1
P
( 1) k 3
x k при x 0,1 .
k k 1
k 0
Вариант 4.11. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить и вывести на печать сумму К членов
числового ряда:
67
K
sin kx
.
k2 k 1
k 0
Вариант 4.12. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить и вывести на печать сумму К членов
числового ряда:
1 1 1
...
S=1
2 3 4
Количество суммируемых членов ряда задается во время работы программы.
Вариант 4.13. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить и вывести на печать сумму членов числового ряда
K
e kx
S
при x 1.
k
!
k 1
( 2) k
S
с точностью. ak 0,0001.
Вариант 4.14. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить и вывести на печать произведение К
членов числового ряда:
K
P
k 1
x k lg kx
.
k2 k 1
Вариант 4.15. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить и вывести в ListBox квадраты К десяти целых положительных чисел, начиная с К1.
Вариант 4.16. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить сумму первых n целых положительных целых чисел, начиная с n1. Количество суммируемых чисел должно вводиться в ListBox .
Вариант 4.17. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить сумму членов числового ряда:
K
e kx / 2
S
при x 1 .
k!
k 1
с точностью ak 0,0001.
Вариант 4.18. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить значения функции у = –2,4х2 + 5х – 3 в
диапазоне от –2 до 2, с шагом 0,5.
Вариант 4.19. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей сгенерировать последовательность из К случайных чисел в диапазоне от 1 до 100, вывести их в ListBox и вычислить их среднее арифметическое.
68
Вариант 4.20. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить значения функции у = |х|. для диапазона изменения аргумента от –N1 до N2, шаг приращения аргумента 0,5 и вывести их в ListBox .
Вариант 4.21. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить сумму членов числового ряда:
K
1 x 2
S
при x 1 .
k
xk 1
k 1 10
ak
.
S
Вариант 4.22. Разработать алгоритм, интерфейс пользователя и написать код программы, позволяющей вычислить значения функции:
x2 y2
f ( x, y )
x3 y 3
при изменении х от –1 до 1 с шагом 0,2 и у от –2 до 2 с шагом 0,5.
Вариант 4.23. Разработать алгоритм, интерфейс пользователя и написать код программы, позволяющей вычислить и вывести в ListBox значения
функции:
x cos(x) y cos(y )
f ( x, y)
x y
при изменении х от 0 до π с шагом π /8 и у от 0 до π с шагом π/16.
Вариант 4.24. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить сумму членов числового ряда:
с точностью
K
S
k 1
1 sin kx cos kx
.
100 k
(kx) 2
с точностью ak 0,0001.
Вариант 4.25. Разработать алгоритм, интерфейс пользователя и написать код программы, позволяющей вычислить и вывести в ListBox значения
функции:
x ln y y lg x
f ( x, y )
x3 y 3
при изменении х от 0 до 2 с шагом 0,1 и у от –2 до 2 с шагом 0,5.
Вариант 4.26. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить и вывести в ListBox нечетные целые
положительные числа в диапазоне от К1 до К2 и их сумму.
Вариант 4.27. Разработать алгоритм, интерфейс пользователя и написать код
программы, позволяющей вычислить сумму К членов числового ряда при Х = Х0.
K
1 1 kx
k
S
.
k
2
1 kx
2
k 0 2
69
Вариант 4.28. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить сумму членов числового ряда:
K
e kx / 2
S
при x 1 .
k!
k 1
с точностью ak 0,0001.
Вариант 4.29. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить и вывести в ListBox значения функции:
f ( x, y )
3
x
y
xy
при изменении х от 0 до 1 с шагом 0,1 и у от 1 до 25 с шагом 2,5.
Вариант 4.30. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей вычислить и вывести в ListBox целые положительные числа, делящиеся на 3 в диапазоне от К1 до К2 и их сумму.
Вариант 4.31. Разработать алгоритм, интерфейс пользователя и написать
код программы, позволяющей оценить относительную точность вычислений с
переменными типа float и double в среде программирования C++ Bilder.
4.3. Контрольные вопросы
1. Какой вычислительный процесс называется циклическим?
2. Что такое цикл, тело цикла, параметр цикла?
3. Каковы обязательные элементы цикла?
4. На какие виды подразделяются арифметические циклы?
5. На какие разновидности делятся циклические процессы?
6. Как графически обозначаются структуры циклов?
7. Какова структура оператора цикла с предусловием, как он выпо лняется?
8. В чем заключаются правила записи и выполнения оператора while?
9. Какова структура оператора цикла с постусловием, как он выполняется?
10. В чем заключаются правила записи и выполнения оператора do ...
while?
11. В чем заключаются правила записи и выполнения оператора for?
12. Как принудительно выйти из любого цикла?
13. Чем отличаются циклы с предусловием от циклов с постусловием?
14. Опишите последовательность функционирования циклов while и do
while. Какой из этих циклов является циклом с предусловием, а какой – с постусловием?
15. Опишите схему работы оператора цикла for. Является ли цикл for циклом с предусловием или циклом с постусловием?
16. Какие циклы называются вложенными?
70
5. ЛАБОРАТОРНАЯ РАБОТА № 4
Тема: «Изучение синтаксиса различных вариантов создания статических
и динамических массивов на языке С++ Builder».
Цель работы. Освоить разработку алгоритмов и программ решения задач
с использованием массивов в среде С++ Builder [1].
5.1. Теоретические сведения.
Массив представляет собой структуру данных, позволяющую хранить совокупность данных любого типа. Массив характеризуется своим именем, типом
хранимых элементов, размером (числом хранимых элементов), нумерацией элементов и размерностью. Массивы могут быть статическими и динамическими,
одномерными и многомерными.
Статическим массивом называется такой массив, число элементов в котором постоянно и заранее определено и задается программистом при разработке
программы.
Динамическим массивом называется массив, в котором число элементов
заранее не известно, оно может быть определено в ходе вычисления в программе или задано пользователем. В динамическом массиве число элементов и размерность могут быть изменены при работе программы.
Объявление статического одномерного массива имеет вид:
<тип_элементов> <имя_ массива> [константное выражение- число
элементов]
Элементы массива могут иметь любой тип. Константное выражение числа элементов должно иметь тип целого без знака.
Например, оператор:
int A[10];
Объявляет массив А, содержащий 10 целых чисел.
char S[10];
Объявляет массив S, содержащий 10 символов.
Можно объявить и многомерный массив, элементами которых являются
массивы. Например, двумерный массив можно объявить таким образом:
Int B [10][5];
Этот оператор описывает двумерный массив, который можно представить
как таблицу, состоящую из 10 строк и 5 столбцов.
Доступ к элементам массива осуществляется выражением:
A[i], B[i][j],
где i и j индексы, являющиеся для данных примеров целыми числами 0 <= i <=
9 и 0 <= j <= 4.
Следует обратить внимание на то, что индекс массива начинается с 0, и
индекс последнего элемента на единицу меньше размера массива.
Перед использованием массива его необходимо инициализировать, т. е.
присвоить элементам массива начальные значения. Начальные значения элементам массива можно задавать при объявлении массива
71
Например:
int A[10] ={2,4,3,6,3,6,1,23,5,25};// массив целых чисел;
char S[10] ={“abcdefghi\0”};// массив символов
По принятому соглашению массивы символов, содержащие строку, после
конца строки обязательно должны содержать нулевой символ. По этой причине
в массиве символов S[10] присутствуют только девять значащих символов, и
последний элемент является нулевым символом.
Если начальных значений меньше, чем элементов массива, то оставшиеся
элементы автоматически инициализируются. Это позволяет инициализировать
символьный массив в более удобной форме:
char kaf_name [ ] = ”кафедра ППБ”;
В этом случае в памяти резервируется 13 битов, ровно столько, сколько
требуется для хранения инициализирующей строки.
При объявлении со списком инициализации размер массива можно не
указывать, тогда количество элементов массива будет равно количеству
элементов в списке начальных значений. Например, объявление Int A [] =
{1,2,3,4,5}; создает массив из пяти элементов.
Если многомерный массив инициализируется при объявлении, список
значений по каждой размерности заключается в фигурные скобки. Например,
инициализация при объявлении трехмерного массива записывается в виде:
Int A3[4] [3] [2] = { {{0,1}, {2,3}, {4,5}},
{{6,7}, {8,9}, {3,8}},
{{1.3}, {5,2}, {8,5}},
{{7,3,1}, {4,5}, {2,9}} };
Эта запись создает массив А3, четыре строки которого являются матрицами размерностью (3 х 2).
Пример 5.1. Необходимо разработать алгоритм, интерфейс пользователя и
программу, позволяющую создать одномерный массив из 100 целых случайных
чисел в диапазоне от 0 до 100, распределенных по равномерному закону, и найти
среднее значение и максимальный элемент и сумму.
Внешняя спецификация задачи:
1. Размерность массива константа – целое число, равное 100.
2. Значения чисел – целые в диапазоне от 0 до 100.
3. Числа должны генерироваться датчиком случайных чисел по равномерному закону.
4. Максимальное число – это целое число в диапазоне от 0 до 100.
5. Сумма чисел массива – целое число, максимальное значение которого не
превысит 10 000.
6. Среднее значение чисел – действительное число.
Алгоритм решения задачи. В начале объявляем массив с заданным числом
элементов. Для генерации элементов массива используем датчик случайных чисел и используя цикл со счетчиком инициализируем массив. Для вывода созданного массива используем объект ListBox. Для поиска максимального элемента,
72
вычисления суммы элементов и среднего значения элемента массива используем
цикл со счетчиком, в теле которого разместим выражение для поиска макс имального элемента, выражение для суммирования членов массива и выражение
для вычисления среднего значения элемента массива. Алгоритм решения задачи
представлен на рис. 5.1.
Начало
Array[100]
I =1,100
Датчик случайных чисел
от 0 -100
Инициализация массива
Вывод массива
I = 1,100
B= max{Array[i]}
s1 = s1 + Array[i]
Cr = s1/100
Вывод b, s1, cr
Конец
Рис. 5.1. Алгоритм решения задачи примера 5.1
73
Разработка интерфейса пользователя. Интерфейс пользователя для программы решения задачи примера 5.1 приведен на рис. 5.2. При проектировании
интерфейса кроме ранее использованных объектов используется объект ListBox
(список), в который можно выводить переменные строкового типа AnsiString.
Поэтому значения элементов массива перед их добавлением в ListBox преобразуются в строковый тип. Добавление элементов в ListBox осуществляется через свойство Items методом Add(Ctr) с использованием конструкции:
AnsiString Ctr;//объявление переменной строкового типа
Ctr = IntToStr(N);// присваивание строковой переменной числа
ListBox1->Items->Add(Ctr);//добавление строки в ListBox:
Рис. 5.2. Интерфейс программы нахождения параметров статического массива
Написание кода программы. При написании программы следует учитывать,
что создание массива и вычисление его параметров управляется двумя командными кнопками, и в функциях обработки событий для этих кнопок используются
одни и те же переменные. Поэтому переменные объявляются вне функций обработки событий и поэтому имеют локальную в пределах формы область видимости. Для того, чтобы датчик случайных чисел к при каждом нажатии на кнопку
Создать генерировал новую последовательность чисел, необходимо в программу
записать в обработчик события void __fastcall TForm1::FormCreate(TObject
*Sender) функцию randomize. Интерфейс программы приведен на рис. 5.2.
Листинг программы создания статического массива и нахождения знач ения его максимального элемента, среднего значения элемента и суммы элементов массива.
74
//--------------------------------------------------------------------------// Обратите внимание! Переменные объявляются вне функции обработчика события и они будут видны во всех процедурах формы
//-------------------------------------------------------------------------int N, i, s1, b;
int Array[100];
float cr;
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString Ctr;
N =0;
i=0;
for(i =0; i<99;i++)
{
Array[i] =random(100);
N = Array[i];
Ctr = IntToStr(N);
ListBox1->Items->Add(Ctr);
}
}
//---------------------------------------------------------------------void __fastcall TForm1::Button2Click(TObject *Sender)
{
Form1->Close();
}
//---------------------------------------------------------------------void __fastcall TForm1::Button3Click(TObject *Sender)
{
cr=0;
b=1;
s1=0;
for( i=0; i<99; i++)
{
s1 = s1+Array[i];
if (Array[i] > b) b = Array[i];
}
cr=(float)s1/100;
Edit1->Text= FloatToStr(cr);
Edit2->Text= IntToStr(b);
Edit3->Text= IntToStr(s1);
}
75
Создание многомерного массива операции с массивами.
Массив в отличие от других видов данных всегда передается в функцию
по ссылке, а не по значению.
Так как массив занимает смежные ячейки памяти, то при использовании
имени массива в качестве аргумента язык С++ обеспечивает передачу функции
адреса первого элемента этого массива.
Имя массива является константным указателем на первый элемент массива, поэтому оно не может модифицироваться и к нему не применимы все операции присваивания.
К имени массива можно применить операцию sizeof, которая возвращает
значение, равное числу элементов (объему) массива, например: sizeof (A) или
sizeof (A[0])
При передачи массива в функцию в качестве параметра заголовок функции содержит тип и имя массива с последующими пустыми квадратными
скобками. например, если функция F должна принимать массив Bs как параметр, ее прототип может иметь вид:
void F(int Bs[ ]);
При вызове функции указывается просто имя массива. Например, обр ащение к такой функции может быть записано в виде:
const Amax =10;
int Bs[Amax];
F(Bs);
В большинстве случаев только имени массива мало, чтобы провести в
функции обработку его элементов, Внутри функции требуется знать размер
массива, чтобы можно было организовать его циклическую обработку, поэтому в функцию передается не только массив, но и его размер. При этом заголовок функции имеет вид:
void F (int Bs[ ], int N);
а вызов функции:
F (Bs, Amax);
При использовании некоторых библиотечных функций необходимо в качестве второго параметра использовать не размер массива, а значение его последнего символа, которое на единицу меньше размеров. В этом случае вызов функции
может иметь вид:
F (Bs, Amax-1);
Передача массива по ссылке не гарантирует защиты от несанкционированного изменения программой значений элементов массива. Если необходимо защитить массив от подобных изменений, его надо передать в функцию как константный:
void F(const int Bs[ ], int N);
При вызове функции не обязательно передавать весь массив. Например, если требуется , то можно передать в функцию параметр размера массива, меньший
истинного. Для этого в качестве начала массива передать в функцию указатель
76
на какой-то элемент массива. Например, если задан массив int Bs[10] и при обращении к функции Вы передадите массив как Sum(Bs-2, Bmax-2), то функция
будет обращаться к элементам массива с индексами от 2 до 7. То есть сумма будет
посчитана по элементам, начиная с третьего.
Если в функцию передается многомерный массив, то в заголовке функции
квадратные скобки первой размерности остаются пустыми, а в скобках следующих размерностей должны указываться константами их размеры. Например, если функция F2 должна принимать двумерный массив размером 3 х 3, то ее заголовок может иметь вид:
void F (const int Bs[ ] [3]);
Вызов этой функции производится передачей в неё имени массива. Например, F(Bs).
Пример 5.2. Разработать интерфейс и программу, позволяющую сгенерировать матрицу размером 5 х 5, элементами которой являются целые числа, распределенные по равномерному закону. Вычислить сумму элементов, находящихся
ниже главной диагонали, и сумму всех элементов матрицы.
Внешняя спецификация задачи.
1. Матрица размерностью 5 х 5 элементов, каждый из которых является целым числом в диапазоне от 0 до 10. Так как матрица представляет статический
двумерный массив, то ее размерность и инициализация должны быть описаны в
программе.
1. Для генерации значений элементов матрицы необходимо использовать
датчик случайных чисел.
2. Результаты вычисления суммы элементов матрицы, лежащих ниже
главной диагонали и суммы всех элементов матрицы являются целыми числами.
Разработка алгоритма решения задачи. Алгоритм решения задачи включает
объявление двухмерной матрицы с заданным числом элементов. Инициализации
матрицы случайными числами, генерируемыми датчиком случайных чисел, организации вывода матрицы в объект StrinGrid. Для определения сумм элементов
матрицы, лежащих ниже главной диагонали, и суммы всех элементов организуются вложенные циклы.
Внешние циклы осуществляют перебор элементов по строкам, внутренние
циклы – перебор по столбцам массива. Схема алгоритма приведена на рис. 5.3.
Разработка пользовательского интерфейса программы. Информация для
пользователя, выводимая на форму, должна содержать размерность матрицы, т. е.
число строк и столбцов, числовые значения элементов матрицы, результаты вычислений сумм.
Для вывода информации о размерности матрицы будем использовать объекты Label .
Для вывода значений элементов матрицы – объект StrinGrid, основными
используемыми свойствами которого являются:
RowCount – количество строк;
77
Начало
Объявление массива
i = 1,5
j = 1,5
a = random(10)
Array[i][j]= a
Вывод
Array[i][j]
i = 2, 5
j = 1, i-1
S = S + Array[i][j]
Вывод s
I = 1, 5
J = 1, 5
S1 = S1 + Array[i][j]
Вывод S1
Конец
Рис.5.3. Алгоритм вычисления суммы элементов двухмерного массива
78
ColCount – количество столбцов;
FixedRows – количество фиксированных строк;
FixedCols – количество фиксированных столбцов.
Метод Cells[i][j] = Array[i][j] заполнение ячеек таблицы элементами массива
Array программным способом. Для того, чтобы можно было заполнять таблицу
StringGrid с клавиатуры, необходимо установить в свойстве Options значение
goEdining, равным True.
Для вывода результатов вычисления суммы элементов, находящихся ниже
главной диагонали матрицы используем объект Label, а для вывода суммы всех
элементов диалоговый модуль сообщений, который вызывается оператором,
имеющим синтаксис:
ShowMessage ("Сумма элементов массива = ” IntToStr(Sum2(Array)))
Для управления программой используем четыре командных кнопки, назначение
которых указывается в свойстве Caption объектов.
Внешний вид интерфейса пользователя приведен на рис. 5.4.
Рис. 5.4. Интерфейс программы вычисления элементов двухмерного массива
Разработка кода программы. Процесс разработки кода программы аналогичен рассмотренному в предыдущем примере. Особенностью является объявление двумерного массива, которое производится в два приема. Вначале объявляется число элементов в каждой размерности массива константами Amax и
Bmax, которые должны учитывать, что число строк и столбцов в объекте StrinGrid на единицу больше, чем число значащих элементов в массиве.
79
Листинг программы вычисления суммы элементов двухмерного массива,
лежащих ниже главной диагонали и суммы всех элементов.
int i, j;
const Amax=6;
const Bmax=6;
int Array[Amax][Bmax];
float cr;
float S;
//-----------------------------------------------------------------------void __fastcall TForm1::Button1Click(TObject *Sender)
{
randomize();
Label7->Caption = IntToStr(Amax-1);
Label8 ->Caption = IntToStr(Bmax-1);
AnsiString Ctr;
i=0;
for (i =1;i<6;i++)
{
StringGrid1->Cells[i][0]= "столбец"+IntToStr(i);
}
for (i =1;i<6;i++)
{
StringGrid1->Cells[0][i]= "строка"+IntToStr(i);
}
for(i =1; i<6;i++)
{
for(j=1; j<6;j++)
{
Array[i][j] =random(10);
StringGrid1->Cells[i][j]= IntToStr(Array[i][j]);
}
}
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button2Click(TObject *Sender)
{
Form1->Close();
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button3Click(TObject *Sender)
80
{
S=0;
for(int i=3; i<6;i++)
{
for(int j=1; j<i;j++)
{
S = S + Array[i][j];
}
}
Label3->Caption = FloatToStr(S);
}
//--------------------------------------------------------------------------int Sum2( int A1[][6])
{
int n1 =6;
int S2 =0;
for (int i=1;i<n1;i++)
{
for (int j=1;j<n1;j++)
{
S2+=A1[i][j];
}
}
return S2;
}
void __fastcall TForm1::Button5Click(TObject *Sender)
{
ShowMessage("Сумма элементов"+IntToStr(Sum2(Array)));
}
Динамические массивы. Динамическое распределение памяти во время
выполнения является чрезвычайно полезной возможностью.
Многие программы интенсивно используют массивы для хранения множества значений определенного типа. При проектировании своих программ
программисты обычно пытаются объявить массивы с размерами, достаточными
для удовлетворения будущих потребностей программы. К сожалению, если
случится так, что потребности программы когда-нибудь превысят подобные
ожидания программиста, то кому-то придется редактировать и перекомпилировать такую программу.
Вместо редактирования и перекомпилирования программ, которые пр осто запрашивают память с запасом, вам следует создавать свои программы таким образом, чтобы они распределяли требуемую им память динамически во
время выполнения. В этом случае ваши программы могут адаптировать ис81
пользование памяти в соответствии с вашими изменившимися потребностями,
избавляя вас от необходимости редактировать и перекомпилировать программу. Распределяя память динамически, ваши программы непрерывно изменяют
свои потребности без дополнительного программирования. Если ваши пр ограммы запрашивают память во время выполнения, они указывают требуемое
количество памяти, а C++ возвращает указатель на эту память.
Язык C++ Builder позволяет распределить память из специальных областей памяти – heap, которые называются свободной пам ятью.
Динамическое распределение памяти в этой области может производиться несколькими способами: с помощью операций new и delete или с помощью
библиотечных функций malloc, calloc, realloc, free. Указанные функции объявлены в файле stdlib.h или alloc.h.
Распределение памяти с помощью операций new и delete.
Следующий фрагмент использует оператор new для получения указателя
на N-байтный массив, число элементов которого N вводится пользователем:
int N
N = StrToInt (Edit1->Text) int *Barray = new int[N];
После выделения памяти под динамический массив необходимо проверить, успешно ли завершилась эта операция. Для этого можно использовать
следующую конструкцию.
if (Barray != NULL) ShowMessage ( "Память успешно выделена")
else
{
ShowMessage ( " Ошибка выделения памяти ");
exit (1);
}
Как видите, программа сразу проверяет значение, присвоенное оператором new переменной-указателю. Если указатель содержит значение NULL, значит new не смог выделить запрашиваемый объем памяти. Если же указатель с одержит не NULL, следовательно, new успешно выделил память и указатель содержит адрес начала блока памяти.
Если new не может удовлетворить запрос на память, он возвратит NULL.
Для размещения в памяти двумерного массива необходимо вначале задать количество строк и столбцов. Затем создать массив указателей на массив
строк и потом циклом задать число элементов в каждой строке.
Например:
int N = StrToInt( Edit1-Text); // число строк
int M = StrToInt( Edit1-Text);// число столбцов
int** Array = new int *[N]; // массив указателей
//на массив строк.
for ( int I = 0; i<N; i++);// массивы указателей на элементы в каждой
строке.
82
Array[i] = new int [M];
Созданный приведенным кодом массив можно использовать как обычный
массив, обращаясь к элементам массива как Array [i][j].
Для освобождения памяти, занятой двумерным массивом, необходимо
удалить все связанные с ним массивы.
Например:
for (int I =0; i<N; i++)
delate[] Array[i];
delate [] A;
При использовании оператора new для выделения памяти может случиться так, что ваш запрос не может быть удовлетворен, поскольку нет достаточного объема свободной памяти. Если оператор new не способен выделить требуемую память, он присваивает указателю значение NULL. Проверяя значение указателя, как показано в предыдущей программе, вы можете определить, был ли
удовлетворен запрос на память.
Динамически распределенную память надо освобождать, когда отпадает
необходимость в размещенных в ней объектах. В противном случае получится
неоправданная утечка памяти.
Удаление памяти осуществляется операцией delete.
Например:
delete Barray;
Barray = NULL;
Для того, чтобы изменить число элементов в массиве созданного опер атором new, необходимо создать вспомогательный массив с числом элементов,
равным исходному. Затем переместить элементы из исходного массива в вспомогательный. Увеличить размер исходного массива и переместить в него элементы из вспомогательного массива и удалить вспомогательный массив.
Распределение памяти с помощью функций malocc, calloc, relloc. Для того, чтобы указанные функции были объявлены в файле stdlib.h alloc.h, которые
записываются в заголовочный файл формы, функция malloc выделяет блок памяти размером size байтов. В случае успешного выделения памяти возвращает
указатель на выделенный блок, в противном случае возвращается NULL. Объявление функции следующее:
void *malloc (size_t size);
Функция calloc выделяет память под несколько объектов, размер каждого из которых равен size. Функция объявляется следующим образом:
void *calloc (size_t n_object, size_t size);
Общий объем выделенной памяти для n объектов составляет n_object*
size. В случае успешного выделения памяти возвращает указатель на выделенный блок, в противном случае возвращается NULL.
Функция realloc позволяет изменить размер ранее выделенного блока
памяти. Функция объявляется следующим образом:
83
void *realloc (void *name_block, size_t size);
Данная функция изменяет размер блока, на который указывает
name_block, до размеров size. При этом предполагается, что block указывает
блок памяти, выделенный ранее функциями malloc, calloc или realloc. Если
блок навого размера не может быть выделен, то функция realloc возвращает
NULL. Если же память выделилась успешно, то возвращается адрес выделенного блока. При этом он может отличаться от начального значения name_block,
поскольку функция при необходимости осуществляет копирование содержимого блока в новое место.
Если размер size задан равным нулю, то выделенный ранее блок, на который указывает name_block, освобождается, а функция возвращает NULL.
Функция free объявляется следующим образом:
void free(void *block);
Она освобождает блок памяти, на который указывает block, выделенный
ранее функциями malloc, calloc или realloc.
Примеры использования описанных функций:
1) int *Carray;
int N;
N = StrToInt(Edit1->Text);
Carray = (int*) malloc(N);
………………….
Free(Carray);
В данном примере функция malloc выделяет память под массив из N целых чисел, где значение N вводится пользователем. После выполнения с массивом каких-либо операций память освобождается функцией free.
2) В этом примере можно было использовать для выделения памяти
функцию calloc;
Carray = (int*) calloc (N) , sizeof(int));
3) Для изменения выделенной памяти применим функцию realloc.
Carray = (int*) realloc ( Carray, N1);
Или более простой оператор:
realoc(Carray, N1);
Пример 5.3. Разработать алгоритм, интерфейс пользователя и программу, позволяющую создать одномерный массив целых чисел, распределенных
по случайному равномерному закону. Число элементов массива и диапазон
значений чисел должны задаваться пользователем. Программа должна осуществлять сортировку массива чисел по убыванию их значений, выводить на
форму исходный и отсортированный массивы и продолжительность сортировки.
Внешняя спецификация задачи.
1. В исходном массиве число элементов определяется пользователем.
2. Элементами массива являются целые положительные числа.
3. Максимальное значение чисел определяется пользователем.
84
4. Значения чисел, заполняющих массив, распределены по равномерному случайному закону.
5. На форму должны выводиться исходный и отсортированный массивы.
6. Продолжительность процесса сортировки должна измеряться с точностью до миллисекунды.
Выбор метода решения задачи.
Создание динамического массива будем производить с помощью опер атора new. Для генерации случайных чисел используем датчик целых чисел,
распределенных по равномерному закону. Сортировку чисел массива будем
производить методом прямого перебора, сущность которого состоит в последовательном сравнении чисел, начиная с первого, со всеми последующими и
определении его места размещения в соответствии с выбранным условием сортировки (по возрастанию либо по уменьшению). Для определения продолжительности процесса сортировки будем засекать начало сортировки и окончание
сортировки – их разность составит продолжительность сортировки.
Разработка алгоритма решения задачи. Алгоритм решения задачи подобен алгоритмам решения предыдущих задач. Поэтому приведем только основные особенности:
1. Объявляются переменные.
2. Осуществляется ввод исходных данных.
3. Создается динамический массив.
4. Осуществляется вывод исходного массива.
5. Засекается по системному времени начало сортировки.
6. Осуществляется сортировка массива.
7. Засекается по системному времени окончание сортировки.
8. Осуществляется вывод продолжительности сортировки.
9. Осуществляется вывод отсортированного массива.
Схема алгоритма приведена на рис. 5.5.
Разработка интерфейса пользователя.
Интерфейс пользователя содержит три текстовых окна для ввода числа
элементов массива и значения максимального значения числа и вывода продо лжительности процесса сортировки. А также метки для информирования пользователя. Для вывода исходного и отсортированного массива используем объект
ListBox. Для управления программой используются две командные кнопки.
Внешний вид интерфейса пользователя приведен на рис. 5.6.
Разработка кода программы.
Особенностями программы является создание динамического массива с
помощью оператора new. Выделение функции прямого перебора, которая описывается вне функций обработки событий. Функция для определения системного времени в момент начала и завершения сортировки взята библиотечная,
синтаксис которой имеет вид:
DecodeTime(Time(), Hour, Min, Sec, MSec),
85
Для ее использования в заголовочный файл формы Unit.h должны быть
включены файлы time.h и DateUtils.hpp.
Начало
int n,u;
Ввод данных
int *Array= new int[n];
Заполнение массива
Вывод массива
Начало сортировки
i = 1, n
J=1, n
Array[i]>Array[j]
m = Array[i];
Array[i] = Array[j];
Array[j] = m;
Конец сортировки
Продолжительности сортировки
Вывод:
Array,
τ- сортировки
Конец
86
Рис 5.5. Алгоритм программы решения задачи сортировки массива
Рис 5.6. Интерфейс пользователя программы создания
и сортировки динамического массива
Листинг программы сортировки динамического массива.
Запишите в заголовочный файл формы подключение файлов для определения времени.
#include <time.h>
#include <DateUtils.hpp>
----------------------------------------------------------------------unsigned int n;
int N,i,u,j,m;
AnsiString Ctr;
int *Array = new int[n];
unsigned short Hour1, Hour2, Min1, Min2, Sec1, Sec2, MSec1, MSec2;
///функция сортировки прямым перебором
void ASort(int Ar[],int k)
{
int m,i,j;
m = 0;
for(i =0; i<(n);i++)
{
87
for(j =0; j<(n);j++)
{
if (Ar[i] > Ar[j])
{
m = Ar[i];
Ar[i]= Ar[j];
Ar[j] =m;
}
}
}
}
…………………………………………………………
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ListBox1->Clear();
ListBox3->Clear();
n = StrToInt(Edit1->Text);
u = StrToInt(Edit2->Text);
int *Array = new int[n];
if (Array != NULL)
{ ShowMessage("Массив успешно создан");
}
else {
ShowMessage("Ошибка выделения памяти");
Abort();
}
N =0;
i=0;
for(i =0; i<(n);i++)
{
Array[i] =random(V);
N = Array[i];
Ctr = IntToStr(N);
ListBox1->Items->Add(Ctr);
}
i=0;
j=0;
m = 0;
// функция определения момента времени начала сортировки
DecodeTime(Time(),Hour1, Min1, Sec1, MSec1);
//Вызов функции сортировки
ASort(Array, n);
//функция определения момента окончания сортировки
88
DecodeTime(Time(),Hour2, Min2, Sec2,MSec2);
// определение продолжительности сортировки,
// как разности времени окончания и начала
Edit3->Text =IntToStr(Sec2-Sec1)+" Sec "+IntToStr(MSec2-MSec1)+" MSec ";
N=0;
// вывод отсортированного массива
for (i =0; i<(n);i++)
{
N = Array[i];
Ctr = IntToStr(N);
ListBox3->Items->Add(Ctr);
}
delete Array;
}
void __fastcall TForm1::Button2Click(TObject *Sender)
{
delete Array;
Array = NULL;
Form1->Close();
}
//--------------------------------------------------------------------------void __fastcall TForm1::FormCreate(TObject *Sender)
{
randomize();
}
//--------------------------------------------------------------------------Протестируйте программу, задавая число элементов в массиве от 10 до
10000 и максимальное значение числа до 1000.
5.2. Задания для самостоятельного выполнения
Вариант 5.1. Разработать алгоритм, интерфейс пользователя и программу, позволяющую в матрице размером 10х10 действительных чисел заменить
нулями все элементы, превышающие среднее значение элемента.
Вариант 5.2. Разработать алгоритм, интерфейс пользователя и программу,
позволяющую упорядочить строки матрицы размером 6х6 по возрастанию значений минимальных элементов этих строк.
Вариант 5.3. Разработать алгоритм, интерфейс пользователя и программу, позволяющую вычислить и записать в массив значения функции y = Ax2
при известных значениях x1, x2, x3, x4 и A.
Вариант 5.4. Разработать алгоритм, интерфейс пользователя и программу, позволяющую создать одномерный массив из 10 целых чисел и дополнить
ее пятью числами и вычислить разность между суммой членов исходным и ко-
89
нечным массивами.
Вариант 5.5. Разработать алгоритм, интерфейс пользователя и программу, позволяющую в матрице размером 10х10 целых чисел вычислить сумму
элементов верхней треугольной матрицы.
Вариант 5.6. Разработать алгоритм, интерфейс пользователя и программу, позволяющую в матрице размером 10х10 найти минимальный элемент в
каждой строке.
Вариант 5.8. Разработать алгоритм, интерфейс пользователя и программу, позволяющую вычислить и вывести в форму первые 10 значений функции:
5
n
z
i 1 k
xik
1 k!
Вариант 5.9. Разработать алгоритм, интерфейс пользователя и программу, позволяющую в массиве B (100) найти сумму 10 наибольших чисел.
Вариант 5.10. Разработать алгоритм, интерфейс пользователя и программу,
позволяющую в одномерном массиве типа int менять местами соседние элементы с
четными и нечетными числами.
Вариант 5.11. Разработать алгоритм, интерфейс пользователя и программу, позволяющую в одномерном массиве типа int менять местами равноудаленные от концов массива элементы.
Вариант 5.12. Разработать алгоритм, интерфейс пользователя и программу, позволяющую почленно суммировать первые четыре элемента двух заданных массивов типа double и помещает результаты в третий массив.
Вариант 5.13. Разработать алгоритм, интерфейс пользователя и программу, позволяющую определить порядковый номер максимального и минимального по абсолютной величине элемента массива типа double.
Вариант 5.14. Разработать алгоритм, интерфейс пользователя и программу, позволяющую определить и вывести в отдельный массив элементы заданного исходного одномерного массива целого типа, а также превышающих
среднее арифметическое значение его элементов.
Вариант 5.15. Разработать алгоритм, интерфейс пользователя и программу, позволяющую вычислить в массиве целого типа квадратный корень из
суммы квадратов значений элементов с нечетными номерами и среднее
арифметическое значение элементов с четными номерами и возвращает
наименьшее из этих двух данных.
Вариант 5.16. Разработать алгоритм, интерфейс пользователя и программу, позволяющую вычислить в массиве целого типа квадратный корень из
суммы квадратов значений элементов с четными номерами и среднее арифметическое значение элементов с нечетными номерами и возвращает
наименьшее из этих двух данных.
Вариант 5.17. Разработать алгоритм, интерфейс пользователя и программу,
позволяющую создать массив, из n элементов найти максимальный и минимальный
элементы и поменять их местами.
90
Вариант 5.18. Разработать алгоритм, интерфейс пользователя и программу, позволяющую создать двумерный массив 6х6 и найти минимальный элемент в каждом ряду и поместить их в первую строку.
Вариант 5.19. Разработать алгоритм, интерфейс пользователя и программу,
позволяющую вычислить значения функции на интервале – [-0,3; 0,5] с интервалом
0,001, и определить максимальный.
Вариант 5.20. Разработать алгоритм, интерфейс пользователя и программу, позволяющую задать матрицу 8х8 и вывести в текстовое окно элементы
главной диагонали.
Вариант 5.21. Разработать алгоритм, интерфейс пользователя и программу, позволяющую создать матрицу NxM целых чисел и вычислить сумму членов выше главной диагонали.
Вариант 5.22. Разработать алгоритм, интерфейс пользователя и программу, позволяющую задать матрицу N x M и заполнить ее случайными числами.
Увеличить число столбцов на 5 и заполнить целыми числами.
Вариант 5.23. Разработать алгоритм, интерфейс пользователя и программу, позволяющую создать матрицу NxM, найти максимальный и минимальный
элементы и поменять их местами.
Вариант 5.24. Разработать алгоритм, интерфейс пользователя и программу, позволяющую создать два одномерных массива N и M элементов N > M. Заполнить первый массив целыми числами и переписать во второй массив M элементов из первого в обратном порядке.
Вариант 5.25. Разработать алгоритм, интерфейс пользователя и программу, позволяющую создать одномерный массив N целых чисел, значения которых распределены по нормальному закону и определить математическое ожидание и дисперсию.
Вариант 5.26. Разработать алгоритм, интерфейс пользователя и программу,
позволяющую одномерный массив N целых чисел распределенных по Пуассоновскому закону, и определить математическое ожидание и дисперсию.
Вариант 5.27. Разработать алгоритм, интерфейс пользователя и программу, позволяющую создать две матрицы N x M, сложить эти матрицы и вычислить минимальный элемент в полученной матрице.
Вариант 5.28. Разработать алгоритм, интерфейс пользователя и программу, позволяющую вычислить значения функции y = (x2 – a) * b2 на интервале от
2a до 2b при условии b > 2a c шагом (b – a) /10.
Вариант 5.29. Разработать алгоритм, интерфейс пользователя и программу, позволяющую вычислить значения функции:
Y = 2 * x8 – 4,3 * x6 + x5 – 1,78 * x3 + x – 1 при –1,5 <= x <= 1,5, ∆ = 0,05
Вариант 5.30. Разработать алгоритм, интерфейс пользователя и программу, позволяющую создать матрицу NxM целых чисел и вычислить сумму членов каждого ряда.
91
5.3. Контрольные вопросы
1. Дайте определение массива.
2. Что понимается под размерностью массива?
3. Какие массивы называются статическими?
4. Как описать одномерные массивы заданной размерности?
5. Как инициализировать одномерный массив?
6. Что означает имя массива без имени?
7. Как объявляются многомерные массивы?
8. Как инициализировать многомерный массив?
9. Как обратиться к элементу массива?
10. Как создать массив, число элементов в котором определяется пользователем?
11. Как увеличить число элементов в одномерном массиве?
12. Как увеличить число элементов в многомерном массиве?
13. Как уменьшить число элементов в массиве?
14. Как вывести элементы массива в объект ListBox?
15. Как ввести элементы массива в объект ListBox c клавиатуры?
16. Как вывести элементы массива в объект StringGrid?
17. Как ввести элементы массива в объект StringGrid с клавиатуры?
18. Какие свойства объекта StringGrid определяют количество строк и
столбцов?
19. Какие операторы и функции используются для удаления массива из
памяти?
6. ЛАБОРАТОРНАЯ РАБОТА № 5
Тема: «Изучение среды C++ Builder. Применение в программах символьных и строковых переменных».
Цель работы: изучение методов применения символьных и строковых типов переменных при разработке программ и интерфейса пользователя [1].
Задачи: разработать алгоритм и программу на языке С++ Builder для обработки переменных символьного и строкового типов данных и использования
стандартных компонентов среды С++ Builder для разработки интерфейса пользователя.
6.1. Теоретический материал
В языке С++ Builder используется один символьный тип данных – char.
Под величину символьного типа отводится один байт, что позволяет хранить в
нем только один символ из 256-символьного набора ASCII.
В С++ Builder строки рассматриваются как массивы символов, оканчивающиеся нулевым символом (\0). Строка доступна через указатель на первый
92
символ в строке.
Строка может быть объявлена либо как массив символов, либо как переменная char*. В качестве примера приводится объявление строковых переменных с одновременной их инициализацией.
сhar Str[]= “студент”; /объявление как массив символов
сhar * St = “студент”; / объявление через указатель
Оба примера идентичны, можно использовать любой из них.
Каждое из приведенных эквивалентных объявлений присваивает строковой переменной значение «строка». Первое объявление создает массив из
8 символов – ‘с’,’т’,’у’,’д’,’е’,’н’,’т’ и символа ‘\0’. Второе объявление создает переменную указателя St, который указывает на строку (массив) с
текстом «студент», лежащую где-то в памяти. Но в любом случае число
хранимых символов на единицу больше числа значащих символов за счет
конечного нулевого символа. Максимальное количество символов, которое
можно сохранить в указанной строковой переменной, равно 256, так как для
одного символа отводится всего один байт.
Доступ к отдельным символам строки осуществляется по индексам,
начинающимся с нуля, например Str[0] и St[0] – первые символы, Str[1] и St[2]
– вторые и т. д. В приведенных примерах длина строк определяется автоматически компилятором. Можно объявлять строковые переменные заданной длины, указывая в квадратных скобках требуемое количество символов. Например,
char Slovo [100] содержит строку из 99 символов.
В некоторых случаях, когда количество символов в строке заранее не известно, нужно использовать динамические массивы с элементами типа char, создание которых рассматривалось в четвертой лабораторной работе.
Например:
1. Объявляется указатель на массив из элементов типа char
char *Sp;
2. Прежде, чем заносить по этому указателю какой-то текст, надо выделить в памяти блок соответствующего размера функциями malloc, calloc или
оператором new;
Str = (char *) malloc(100);
Str = (char *)relloc (Str, 100);
chart *Srr = new char[N];
Для того, чтобы выделить память под строку, записанную в окне Edit,
используется конструкция:
Str = (char *) malloc(strlen (Edit1->Text.c_str()) +1);
где c_str() – функция преобразования строки типа AnsiString в строку типа char.
Для того, чтобы занести в строку текст из окна, применяется выражение
ctrcpy(St, Edit1->Text.c_str());
Можно также воспользоваться функцией StrAlloc, например:
shar *St = StrAlloc(strlen (Edit1->Text.c_str()) +1);
выделяется блок памяти, в который заносится содержимое Edit.
93
В этом выражении функция strlen определяет количество символов
в окне и добавляет еще один символ для нулев ого символа.
Если требуется изменить (увеличить) размер блока памяти, на который
указывает St, можно сделать функцией realloc:
realocc (St, strlen(“дополнительный текст”) +1);
и затем в строку добавить новый текст:
strcpy (Sp, “дополнительный текст”);
Для обработки строк имеется ряд библиотечных функций, которые приведены в табл. 6.1.
Таблица 6.1
Библиотечные функции работы со строками типа char
(для символов кириллицы)
Функция
strcat
(StrCat)
strcpy
AnsiStrComp
strstr
strlen
AnsiStrUpper
sprintf
strchr
strtok
free
StrNew
StrECopy
Синтаксис
Описание
char *strcat (char *S1, const Конкатенация. Добавляет строку S2 в
char *S2)
конец строки S1
char *strcpy (char *S1, Копирует строку S2 в строку S1
const char *S2)
int AnsiStrComp (char *S1, Сравнивает строки S1 и S2; c учетом
char *S2)
регистра. Результат <0 при S1<S2, = 0
при S1 = S2 и >0 при S1>.S2
char *strstr(const char *S1, Возвращает первое вхождение строки
char *S2)
S1 в строку S1
size_t strlen( const char*S)
Определяет число символов в строке S,
не считая нулевого)
char*AnsiStrUpper(char S1) Преобразование символов строки S1 к
верхнему регистру
Построение строки по заданному
шаблону форматирования и списку
аргументов
char *strсhr(const char *S, Возвращает указатель на первое
int C)
вхождение C в S
char *strtok(char *S1, const Ищет первое вхождение разделителей
char*s2)
из строки S2 в строке S1 и усекает
строку S1. Возможны повторения
free(S)
Освобождает память, выделенную под
строку
StrNew(const char*Str)
Создает в памяти копию строки Str и
заполняет ее символами исходной
строки
StrECopy(S, S1)
Копирует строку S1 в строку S и возвращает указатель на последний символ скопированной строки
Примеры использования библиотечных функций обработки строковых
переменных:
1. Пусть объявлен массив символов St [50]; Для того, чтобы занести в не94
го какой-либо текст нужно применить функцию strcpy: strcpy (St, “Текст копируемый в St”);
2. Пусть необходимо в конец первой строки St1 прибавить текст, хранящийся в строке St2. Это можно сделать с помощью функции strcat:
char St1[20] = “текст 1, St2[10]= “ Текст2”;
stract (St1, St2);
При записи данного алгоритма размер первой строки выбирается с запасом, чтобы можно было разместить второй текст.
Операции, связанные с выделением памяти под строку и занесением в неё
текста строки, довольно громоздки и часто служат причиной ошибок. Ошибка в
выделении памяти не замечается во время компиляции, а во время выполнения
программы, если длина строки окажется больше, чем выделено памяти, то последние символы строки сотрут какие-то другие данные в памяти, что может
привести к грубым ошибкам и зависанию программы. В этой связи необходимо
при выделении памяти ставить обработчик исключений.
Строковые переменные типа AnsiString.
В языке С++Builder реализован тип строк AnsiString как класс, объявленный в файле vc/dstring.h. данный тип строк аналогичен типу данных строк в
Delphi. Это тоже строка с нулевым символом на конце, как и строки char*.
Каждый символ в строке AnsiString занимает 8 бит.
Существенным достоинством типа AnsiString является то, что число символов в строке AnsiString лимитировано только объемом памяти компьютера.
Память под строки выделяется динамически, причем программисту не приходится об этом думать. Строки AnsiString позволяют работать с символами кириллицы и русского языка, учитывают принятые способы отображения дат и
времени.
Со строками AnsiString намного проще, чем при использовании char*:
осуществляется занесение текста в строку, объединение нескольких строк, р абота с компонентами C++ Builder.
Тип AnsiString используется для ряда свойств компонентов C++ Builder,
например, свойства Text окна редактирования, свойства Caption меток, разделов
меню и т. д. Этот же тип используется для отображения отдельных строк в списках строк типа TStrings.
Поэтому, если нет каких-то иных весомых соображений, всегда целесообразно работать со строками AnsiString.
При объявлении строковых переменных типа AnsiString они инициализируются пустыми строками и имеют вид:
AnsiString S1, S2, S3;
Переменные этого типа можно объявлять и как переменные String – это
просто псевдоним AnsiString.
Несмотря на то, что применение строкового типа AnsiString практически
всегда удобнее (char*), иногда требуется осуществить переход к типу char*.
Такие переходы приходится делать при передаче параметров в некоторые
95
функции, чаще всего это связано с вызовом функций API Windows или функций C++ Builder, инкапсулирующих такие функции.
Преобразование строки AnsiString в строку (char*) осуществляется функцией c_str() без параметров, возвращающей строку с нулевым символом в конце, содержащую текст той строки AnsiString, к которой она применена.
Например, если имеются строки S1 и S2 типа AnsiString, которые необходимо передать в функцию Application -> MessageBox в качестве сообщения и заголовка окна, то вызов Application -> MessageBox может иметь вид:
Application -> MessageBox(S1.c_str(), S2.c_str(), MB_OK);
Возможно и обратное преобразование строки (char*) в строку AnsiString
для этого используется функция:
AnsiString (char *S);
которая возвращает строку типа AnsiString, содержащую текст, записанный в
строке S, являющейся аргументом функции.
Для AnsiString определены операции отношения: ==, >, <, >=, <=. Сравнение производится с учетом регистров.
Для AnsiString определенны также операции присваивания =, +=, операция склеивания (конкатенации), а также операция индексации [ ], индексы
начинаются с 1.
Класс имеет множество методов и библиотечных функций, которые позволяют эффективно работать с переменными указанного типа. Подробное описание функций можно найти в руководстве по языку C++ Builder. Некоторые из
наиболее распространенных функций приведены в табл. 6.2.
Таблица 6.2
Основные функции работы со строками типа AnsiString
Функция
Lenght
SetLenght
Синтаксис
S.Length()
SetLength (S, int newLength )
Создание копии AnsiString S2 = Anстроки
siString S1
StringOfChar
StringOfChar(char ch, int
count)
Pos
SubString
Описание
Возвращает длину строки S в байтах
Позволяет уменьшить длину строки
S до newLenght символов
Создает строку S2, являющуюся копией строки S1
Заполняет строку N (count) символами ch
S. Pos (const An- Функция ищет в строке S первое
siString& subStr) const
вхождение подстроки, заданной ее параметром subStr (S2). Если поиск
успешный, функция возвращает индекс первого символа найденного
вхождения подстроки
SubString (int index, int Возвращает строку, начинающуюся с
count)
символа в позиции, заданной параметром count
96
Продолжение табл. 6.2
Функция
Trim
Синтаксис
Trim(S)
MidStr
MidStr (count AnsiString Возвращает подстроку AText, начиAText, int AStart, int нающуюся с символа в позиции AStart
ACount)
и содержащую число символов, не
превышающее ACount
LeftStr( const AnsiString Возвращает фрагмент из ACount симAText, int ACount)
волов, с которого начинается строка
AText
LeftStr
Описание
Возвращает строку, соответствующую
исходной, но без пробельных символов до и после значащих символов
An- Возвращает фрагмент из ACount симint волов, которым заканчивается строка
AText
RightStr
RightStr(
const
siString AText,
ACount)
Delete
S. Delete (int index, int Удаляет из строки S, начиная с позиcount)
ции, заданной параметром index, число символов, заданное параметром
count
S. Insert (const An- Вставляет в строку S подстроку, заsiString& str, int index
данную параметром str, в позицию,
заданную параметром index
Insert
TrimLeft
TrimLeft(S)
TrimRight
TrimRight(S)
Возвращает строку, соответствующую
исходной, но без начальных пробельных символов
Возвращает строку, соответствующую
исходной, но без заключительных пробельных символов
Рассмотрим некоторые примеры.
Пример 6.1.
Разработать алгоритм, интерфейс пользователя и программу, позволяющую найти в предложении St1 первое вхождение слова St2, и если это слово
присутствует, заменить его на фрагмент, содержащийся в строке St3. При создании программы использовать как строки типа char*, так и AnsiString.
Выбор метода решения. Одним из возможных методов решения задачи
является просмотр последовательно всех символов в предложении, выделение
слов, находящихся между двух пробелов и сравнение этих слов с требуемым. В
случае совпадения произвести последовательную замену символов найденного
слова на символы требуемого слова.
Однако использование библиотечных функций позволяет существенно
упростить решение поставленной задачи.
Для решения задачи с применением строковых переменных типа char
применим три функции (см. табл. 5.1):
– функцию strstr (S1, S2), которая ищет в строке S1 первое вхождение
97
строки S2 и если поиск прошел удачно, то возвращает указатель на первый
символ этого вхождения;
– strcpy (S, S3), которая копирует в строку S строку, на которую указывает S3;
– strcat (S, S2), позволяющую добавить в конец строки S строку S2;
– strlen (S) – определяет число символов в строке S, не считая нулевого.
Для решения задачи с применением строковых переменных типа AnsiString применим функции (см. табл. 5.2):
- c_str() – преобразование строки AnsiString в строку char*;
- S.Pos( S2) – функция ищет в строке S первое вхождение подстроки, заданной ее параметром subStr (S2);
- SubString (k,n) – возвращает строку, начинающуюся с символа в позиции
k, c числом символов n;
- Length(), – возвращает длину строки S в байтах.
Разработка интерфейса пользователя.
Создайте проект и разместите на форме две командные кнопки для управления программой, три текстовых окна с метками, надписи в которых указывают
их назначение для ввода исходных данных, два переключателя RadioButton для
выбора типа используемых типов строк. Результаты преобразования строк будем
выводить в метки. Внешний вид формы проекта приведен на рис. 6.1.
Разработка кода программы.
Программа состоит из двух подпрограмм. В первой подпрограмме выполняется замена слова в предложении с использованием строк типа char, во второй
– с использованием строк типа AnsiString, Переключение между подпрограммами осуществляется с использованием переключателей.
Рис. 6.1. Форма для программы замены слова в предложении
98
В первой подпрограмме помимо строк St1, St2, St3 объявлена строка St,
являющаяся буфером, в который будет помещаться результирующий текст.
Объявлен также указатель на строку Sb, которая требуется в качестве вспомогательной переменной. Ввод исходного предложения, заменяемого и заменяющего слов вводится в окна Edit. Так как текст, введенный в окна Edit имеет тип
AnsiString, то для преобразование их к типу char применяется функция c_str( ).
Первый выполняемый оператор кода ищет с помощью функции strstr
вхождение строки St2 в сторку St1 и присваивает результат поиска переменной
Sb. Если поиск не дал результата, то функция strstr возвращает нуль и печатается сообщение «Текст не найден». Если же поиск прошел успешно, то осуществляются следующие операции. Сначала в символ, на который указывает Sb, засылается 0 – это эквивалентно нулевому символу. Таким образом выделяется первая часть строки St1, расположенная до заменяющего текста. Затем указатель Sb
сдвигается на длину заменяемого текста, которая определяется функцией strlen.
После этой операции Sb начинает указывать на первый символ строки S1 после
заменяемого текста. Следующий оператор формирует в буфере St текст с заменой и отображает его в метке Label1. Формирование текста осуществляется вложенными вызовами функций strcat и strcpy. Последний внешний вызов strcat добавляет к сформированному тексту часть строки St1, расположенную после замененного фрагмента. Именно на эту часть строки указывает Sb.
Результат выводится в метку Label.
Во второй подпрограмме для строк типа AnsiString использован ряд
функций класса AnsiServer; Pos, SubString, Length. Обратите внимание на то,
что обращение к указанным функциям осуществляется операцией (.) – njxrf
вместо более привычной в C++ Builder операции доступа к методам и свойствам объектов (–>). Первый выполняемый оператор использует функцию
Pos(S2) для поиска в строке S1 первое вхождение фрагмента S2. Если поиск
успешный, функция возвращает индекс первого символа найденного фрагмента, в противном случае – нуль. Индексы начинаются с нуля. Если Индекс не
равен нулю, то производится формирование строки с заменой найденной подстроки. Строка формируется склеиванием трех строк: начальной части строки
S1, для получения которой используется функция SubString. Аналогично выражение S1.SubString (i+S2.Length(), 225) – часть строки S1, расположенная после
найденного вхождения фрагмента S2. В приведенном выражении в качестве
второго параметра функции SubString задано число 255, которое, как ожидается, превышает длину подстроки. Результат выводится в метку Label. Листинг
программы приводится ниже.
Листинг программы замены слова в предложении
void __fastcall TFStr1::Button1Click(TObject *Sender)
{
if (RadioButton1->Checked)
//Программа для строки типа char*
{
char St[100];
99
char *Sb;
AnsiString S,S1,S2; //вспомогательная переменная
S = Edit1 ->Text; // предложение char *St1 =S.c_str();
// преобразование строки AnsiString в строку char*
S1 = Edit2 ->Text; // слово, которое надо заменить
char* St2 = S1.c_str();
S2 = Edit3 ->Text;// слово, которое надо вставить
char* St3 = S2.c_str();
Sb = strstr(St1, St2);
if(Sb)
{
*Sb = 0;
Sb += strlen(St2);
Label1 -> Caption = strcat(strcat(strcpy(St,St1),St3),Sb);
}
else Label1 -> Caption = "Текст не найден";
}
Else
//Программа для строки типа AnsiString
{
AnsiString S1,S2, S3;
int i;
S1 = Edit1->Text;
S2 = Edit2->Text;
S3 = Edit3->Text;
i =S1.Pos(S2);
if(i)
Label8->Caption=S1.SubString(1,i-1)+S3
+S1.SubString(i+S2.Length(),255);
else
Label8->Caption ="Текст не найден";
}
}
//--------------------------------------------------------------------------void __fastcall TFStr1::Button2Click(TObject *Sender)
{
FStr1 -> Close();
}
Пример 6.2. Разработать алгоритм, интерфейс пользователя и программу,
позволяющую определить введенное пользователем слово на русском языке
строчными буквами.
Алгоритм решения поставленной задачи состоит в следующем:
1. Определяем количество букв в слове (длину слова).
2. Слово в языке С++ является массивом символов, поэтому выбирая
100
элемент массива, можно сравнить его в цикле с буквами алфавита, который
также задается словом (массивом).
3. Определив совпадение первого выбранного элемента с элементом массива
алфавита, переходим к следующему элементу. Таким образом алгоритм включает
вложенные циклы со счетчиком.
Внешний цикл – выбор последовательности элементов в слове.
Внутренний – проверка совпадения элемента слова с буквой алфавита.
Интерфейс пользователя приведен на рис. 6.2. Вводимое слово не маскируется для того, чтобы можно было проверить работу программы.
Рис 6.2 Интерфейс пользователя к примеру 6.2
Листинг программы определения введенного слова
//--------------------------------------------------------------------------void __fastcall TFormS2::Button1Click(TObject *Sender)
{
FormS2->Close();
}
//--------------------------------------------------------------------------void __fastcall TFormS2::Button2Click(TObject *Sender)
{
int i,j;
101
AnsiString Old,Nov,st1;
AnsiString d,c;
Old = Edit1->Text;
Nov = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя";
int n = Old.Length();
Edit3->Text = Old[1];
Edit4->Text= n;
for(i=1; i<=Old.Length();i++)
{
for(j=1;j<=Nov.Length(); j++)
{
if (Old[i]==Nov[j]) st1+=Nov[j];
}
}
Edit5->Text = st1;
}
Пример 6.3. Напишем код функции, позволяющий заменить первую
строчную букву слова на прописную (верхнего регистра).
Содержание алгоритма состоит в следующем:
1. Выделить первую букву слова.
2. Заменить первую букву слова на прописную и сохранить.
3. Удалить первую букву из слова.
4. Вставить на ее место сохраненную прописную букву.
5. Интерфейс пользователя приведен на рис. 6.3.
Рис.6.3. Интерфейс пользователя к примеру 6.3
102
Код функции, написанный для события Button1Click, приведен ниже.
При разработке кода была создана функция AnsiString UCas(AnsiString R,
AnsiString R1), которая объявляется и определяется в файле реализации формы
в разделе конструктора формы. В обработчике события используется вызов
указанной функции.
fastcall TFormBB::TFormBB(TComponent* Owner)
: TForm(Owner)
{
//объявление функции
AnsiString UCas(AnsiString R, AnsiString R1);
}
//---------------------------------------------------------------Определение функции
AnsiString UCas(AnsiString R, AnsiString R1)
{
AnsiString b = AnsiUpperCase(R[1]); //первая буква слова делается прописной и сохраняется в переменной b
AnsiString C = R.Delete(1,1); // удаляется первая буква из слова
R1 = b+C;// к слову присоединяется прописная первая буква
return R1;
}
void __fastcall TFormBB::Button1Click(TObject *Sender)
{
AnsiString S1, b,C,R1;
S1= Edit1->Text;
Edit2->Text = UCas(S1,R1);// вызов функции
}
//--------------------------------------------------------------------------void __fastcall TFormBB::Button1Click(TObject *Sender)
{
FormBB->Close();
}
Запустим программу и введем слово в Edit1 cо строчной буквы и переместим курсор на другое окно. Мы увидим, что первая буква изменилась на пр описную. Данная функция может использоваться в программах для парирования
ошибок пользователя при вводе слов.
6.2. Структуры в языке C++ Builder
Структуры – это составные типы данных, построенные с использованием других типов. Они представляют собой объединенный общим именем набор
данных различных типов. Именно тем, что в них могут хранится данные разных
типов, они и отличаются от массивов, хранящих данные одного типа.
103
Отдельные данные структуры называются элементами или полями. Все
это напоминает запись в базе данных, только хранящуюся в оперативной памяти компьютера.
Простейший вариант объявления структуры может выглядеть следующим
образом:
struct TPers {
AnsiString Fam,Nam,Par;
unsigned Year;
bool Yes;
AnsiString Dep;
};
Ключевое слово struct начинает определение структуры. Идентификатор
TPers – тег (обозначение, имя-этикетка) структуры. Тег структуры используется
при объявлении переменных структур данного типа. В этом примере имя нового
типа – TPers. Имена, объявленные в фигурных скобках описания структуры, – это
элементы структуры. Элементы одной и той же структуры должны иметь уникальные имена, но две разные структуры могут содержать не конфликтующие элементы
с одинаковыми именами. Каждое определение структуры должно заканчиваться
точкой с запятой.
Определение TPers содержит шесть элементов. Предполагается, что такая
структура может хранить данные о сотруднике некоего учреждения. Типы данных
разные: элементы Fam, Nam, Par и Dep – строки, хранящие соответственно фамилию, имя, отчество сотрудника и название отдела, в котором он работает. Элемент
Year целого типа хранит год рождения, элемент Yes булева типа хранит сведения о
поле. Элементы структуры могут быть любого типа, но структура не может с одержать экземпляры самой себя.
Например, элемент типа TPers не может быть объявлен в определении
структуры TPers. Однако может быть включен указатель на другую структуру
типа TPers. Структура, содержащая элемент, который является указателем на
такой же структурный тип, называется структурой с самоадресацией. Такие
структуры очень полезны для формирования различных списков.
Само по себе объявление структуры не резервирует никакого пространства в памяти; оно только создает новый тип данных, который может использ оваться для объявления переменных. Переменные структуры объявляются так
же, как переменные других типов. Объявление:
TPers Pers, PersArray[10], *Ppers;
объявляет переменную Pers типа TPers, массив PersArray – с 10 элементами типа TPers и указатель Ppers на объект типа TPers.
Переменные структуры могут объявляться и непосредственно в объявлении самой структуры после закрывающейся фигурной скобки. В этом случае
указание тега не обязательно:
Struct {
AnsiString Fam,Nam,Par;
unsigned Year;
104
bool Yes;
AnsiString Dep;
}
Pers, PersArray[10], *Ppers;
Для доступа к элементам структуры используются операции доступа к элементам: операция точка (.) и операция стрелка (->). Операция точка обращается к
элементу структуры по имени объекта или по ссылке на объект. Например:
Pers.Fam = "Иванов";
Pers.Nam = "Иван";
Pers.Par = "Иванович";
Pers.Year = 1960;
Pers.Yes = true;
Pers.Dep = "Бухгалтерия";
Операция стрелка обеспечивает доступ к элементу структуры через указатель на объект. Допустим, что выполнен оператор
Ppers = SPers;
который присвоил указателю Ppers адрес объекта Pers. Тогда указанные
выше присваивания элементам структуры можно выполнить так:
Ppers->Fam = "Иванов";
Ppers->Nam = "Иван";
Ppers->Par = "Иванович";
Ppers->Year = 1960; Ppers->Yes = true;
Ppers->Dep = "Бухгалтерия";
Пример 6.4. Разработать алгоритм, интерфейс пользователя и программу, позволяющую вести ведомость успеваемости студентов и позволяющую находить данные о студенте по введенной фамилии.
Внешняя спецификация программы.
Исходные данные:
Фамилия студента содержит не более 15 букв.
Инициалы студента содержат две прописные буквы, точка между ними и
после второй буквы всего четыре символа.
Номер учебной группы (ИН-066) содержит шесть символов.
Оценка по дисциплине 1 содержит один символ.
Оценка по дисциплине 2 содержит один символ.
Ведомость успеваемости должна быть представлена в табличной форме,
программа должна позволять вводить дополнительные записи и в случае ошибки
в записи, должна позволять корректировать записи. Поиск данных о студенте
должен производиться по фамилии и результаты должны выводиться в таблицу.
Выбор способа решения задачи.
Данные о студенте (запись) представим как переменную типа структура
(struct). Для обеспечения ввода данных будем использовать диалоговое окно
InputBox. Данные о студентах и результаты поиска будем размещать в объектах
StringGrid.
105
Разработка алгоритма решения задачи.
Применительно к поставленной задаче приведем словесное описание алгоритма, так как основные трудности решения данной задачи заключаются в
правильном написании кода программы и использовании свойств объектов и
стандартных функций.
Алгоритм решения задачи включает следующую последовательность
действий.
1. Формируем базу данных (в данной задаче примитивную) об успеваемости студентов.
2.Заполняем базу данных сведениями об успеваемости студентов.
3. Выводим таблицу с данными об успеваемости студентов на экран для
визуального контроля.
4. Если при внесении данных допущена ошибка, открываем доступ к
таблице для непосредственной корректировки записей.
5. Создаем файл для сохранения базы данных и открываем его для записи.
6. Сохраняем таблицу с данными об успеваемости студентов в созданном
файле.
7. Открываем файл для чтения.
8. Считываем данные из файла в таблицу.
9. Вводим фамилию студента, успеваемость которого необходимо просмотреть.
10. Осуществляем поиск данных об успеваемости студента в таблице.
11. Выводим данные об успеваемости студента для просмотра.
Рис. 6.4. Интерфейс пользователя программы «Ведомость успеваемости»
106
Разработка интерфейса пользователя.
Интерфейс включает два объекта StringGrid, у которых верхняя строка является
фиксированной, в которую выводятся заголовки столбцов. Для этого значению
свойства FixedCols объекта присвоим 0, а свойству FixedRows – 1. Для обеспечения доступа к таблице cвойству goEditing свойства Options объекта присвоим
значение false (запрет на доступ к полям таблицы). Для управления доступом в
обработчик события командной кнопке исправить запишем выражение, переводящее значение этого свойства в True (разрешающее доступ к полям таблицы).
Свойству Visible присвоим значение false, что делает таблицу 2 невидимой, и в
обработчике события для кнопки Найти свойству Visible присвоим значение
true, что сделает таблицу 2 видимой при осуществлении поиска. Интерфейс
пользователя приведен на рис. 6.4. Подробные комментарии к операторам пр ограммы, поясняющие семантику, приводятся в листинге программы.
Листинг программы
////Объявление функции считывания записи
int GetLine(int f, AnsiString *st);
//объявление структуры
struct TStudent{
AnsiString Fam,Inic,Grup,D1,D2;
};
void __fastcall TFSpisok::Button1Click(TObject *Sender)
{
FSpisok->Close(); //завершение работы программы
}
//--------------------------------------------------------------------------int i;
//присваивание наименований столбцам таблицы 1
void __fastcall TFSpisok::FormCreate(TObject *Sender)
{
StringGrid1->Cells[0][0]= "№ п/п";
StringGrid1->Cells[1][0]= "Фамилия";
StringGrid1->Cells[2][0]= "Инициалы";
StringGrid1->Cells[3][0]= "Группа";
StringGrid1->Cells[4][0]= "Программирование";
StringGrid1->Cells[5][0]= "Комп. технолог.";
StringGrid1->Options << goEditing;// разрешение непосредс//твенного доступа к полям таблицы
StringGrid1->Options << goTabs; // Перемещение по полям
//таблицы с помощью клавиши Tab
///присваивание наименований столбцам таблицы 2
StringGrid2->Cells[0][0]= "№ п/п";
StringGrid2->Cells[1][0]= " Фамилия ";
StringGrid2->Cells[2][0]= " Инициалы ";
107
StringGrid2->Cells[3][0]= " Группа ";
StringGrid2->Cells[4][0]= " Прогр. ЯВУ ";
StringGrid1->Cells[5][0]= " Техн. прогр.";
}
//------------------------------------------------------------------void __fastcall TFSpisok::BitBtn1Click(TObject *Sender)
{
int i,j;
int index,index0;
int num;
int Lstr;
AnsiString Lst;
TStudent Student1;
Student1.Fam = InputBox("Ввод данных о студенте","Введите
фамилию",Name);
Student1.Inic = InputBox("Ввод данных о студенте","Введите инициалы","Пусто");
Student1.Grup = InputBox("Ввод данных о студенте","Введите группу","Пусто");
Student1.D1 =InputBox("Ввод данных о студенте","Введите оценку по
Программированию","Пусто");
Student1.D2 = InputBox("Ввод данных о студенте","Введите оценку по
Комп. технолог.","Пусто");
//определение числа строк в таблице
index0 = StringGrid1->RowCount;
// определение номера последней записи
for (i=0; i <index0;i++)
{
Lst= StringGrid1->Cells[1][i];
Lstr =Lst.Length(); //определение длины записи в 1-м столбце i-ой
строки
if (Lstr==0) break;
index = i; // индекс последней записи
}
//проверка необходимости увеличения числа строк на 1
if(index <(index0 -1)) StringGrid1->RowCount=(index0+1);
num=index +1; // индекс следующей записи
StringGrid1->Cells[0][num]= num;// запись номера по порядку
//добавление следующей записи в таблицу
StringGrid1->Cells[1][num]=Student1.Fam;
StringGrid1->Cells[2][num]=Student1.Inic;
StringGrid1->Cells[3][num]=Student1.Grup;
StringGrid1->Cells[4][num]=Student1.D1;
108
StringGrid1->Cells[5][num]=Student1.D2;
}
//-------------------------------------------------------------------//функция для обработки события командной кнопки Исправить таблицу
void __fastcall TFSpisok::Button2Click(TObject *Sender)
{
StringGrid1->Enabled=true; //открытие доступа к таблице }
//----------------------------------------------------------------------//--------------------------------------------------------------------//Функция обработки события командной кнопки Найти
void __fastcall TFSpisok::Button3Click(TObject *Sender)
{
StringGrid2->Visible = true;
AnsiString s1,s2;
s1 = Edit1->Text;
for (i=1; i<=StringGrid1->RowCount; i++)
{
s2= StringGrid1->Cells[1][i];
if(s1==s2) break;
}
StringGrid2->Rows[1]=StringGrid1->Rows[i];
}
//--------------------------------------------------------------------------//Функция обработки события командной кнопки сохранить в файл
void __fastcall TFSpisok::Button4Click(TObject *Sender)
{
int f; //дискриптор файла
//открыть существующий файл, если его нет, создать новый
if (FileExists("tab1.grd"))
f= FileOpen("tab1.grd",fmOpenWrite); // Открыть файл на запись
else
f = FileCreate("tab1.grd");
if (f!=-1)
{
for (int i =1; i<StringGrid1->RowCount; i++)
{
// формирование строки, оканчивающейся символами конец строки и
перевод каретки
AnsiString st = StringGrid1->Rows[i]->DelimitedText+"\r\n";
FileWrite(f,st.c_str(), st.Length()); //запись строки в файл
}
FileClose(f);//закрытие файла
}
109
else
ShowMessage("ошибка доступа к файлу");
}
//---------------------------------------------------------------------void __fastcall TFSpisok::Button5Click(TObject *Sender)
{
// функция обработки события командной кнопки Загрузить из файла
int f;
AnsiString st;
bool f1=true;
if((f = FileOpen("tab1.grd",fmOpenRead))==-1)
return;
while (GetLine(f,&st) !=0)
{
if (f1)
{
StringGrid1->Rows[StringGrid1->Row] -> DelimitedText= st;
f1= false;
}
else
{
StringGrid1->RowCount++;
StringGrid1->Row = StringGrid1->RowCount -1;
StringGrid1->Rows[StringGrid1->Row]-> DelimitedText=st;
}
}
FileClose(f);
}
//читает из файла строку символов
//от текущей позиции до символа конец строки
//значение функции количество прочитанных символов
int GetLine (int f, AnsiString *st)
{
//unsigned char buf[256]; //задаем величину буфера для считывания символов строки
unsigned char *p = buf;// указатель на строку
int n;//количество прочитанных байт
int len = 0;// длина строки
n = FileRead(f,p,1); // стандартная функция считывания байт из файла
while (n!= 0)//
{
if(*p =='\r')
{ n = FileRead(f,p,1); //считывание символов строки
110
break;
}
len++;
p++;
n = FileRead(f,p,1);
}
*p = '\0';
if (len !=0)// если длина записи не равна 0. Считанные байты из буфера
записываются в переменную st
st -> printf("%s",buf);
return len;
}
Запустите программы, отладьте и протестируйте.
6.3. Задания для самостоятельной работы
Вариант 6.1. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую определить число слов в предложении.
Вариант 6.2. Разработайте алгоритм, интерфейс пользователя и программу,
позволяющую определить число букв в предложении.
Вариант 6.3. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую определить число гласных букв в предложении.
Вариант 6.4. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую определить частоту одинаковых слов в предложении.
Вариант 6.5. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую составить список телефонов сотрудников и осуществлять
поиск номера телефона по фамилии.
Вариант 6.6. Разработайте алгоритм, интерфейс пользователя и
программу, позволяющую определить частоту гласных букв в слове.
Вариант 6.7. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую преобразовать в прописные буквы весь введенный текст.
Вариант 6.8. Задача «Города». Широко известна игра «Города». Называется какой-нибудь город, допустим, «Саратов». Кончается на «в», значит название
другого города, должно начинаться с буквы «в». Это может быть «Воронеж».
Следующий город должен начинаться на «ж» и т. д. Запрещено повторять название городов. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую из набора названий городов (все названия разные) строить цепочку
максимальной длины.
Вариант 6.9. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую определить число согласных букв в предложении.
Вариант 6.10. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую определить число слов в двух предложениях.
Вариант 6.11. Разработайте алгоритм, интерфейс пользователя и програм-
111
му, позволяющую произвести инвертирование слова.
Вариант 6.12. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую упорядочить по первой букве список сочетаний из 4
случайных букв, задаваемых датчиком случайных чисел.
Вариант 6.13. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую упорядочить по двум начальным буквам фамилии список сотрудников, содержащий фамилию и инициалы.
Вариант 6.14. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую упорядочить по начальной букве фамилии список сотрудников,
содержащий фамилию и инициалы.
Вариант 6.15. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую упорядочить по начальной букве, фамилии и инициалам
список сотрудников, содержащий фамилию и инициалы.
Вариант 6.16. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую упорядочить по начальной букве фамилии записи в ведомости успеваемости студентов.
Вариант 6.17. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую составить из нескольких слов, (подлежащего, сказуемого и дополнения) предложение.
Вариант 6.18. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую распознать слово, содержащее прописные и стро чные
буквы.
Вариант 6.19. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую предупредить пользователя о том, что он вводит данные
английским шрифтом.
Вариант 6.20. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую предупредить пользователя, что он забыл ввести в окно
Edit данные.
Вариант 6.21. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую предупредить пользователя о том, что он вместо текста
ввел в окно Edit цифры.
Вариант 6.22. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую определить, какое четырехзначное число пользователь
ввел в оно Edit.
Вариант 6.23. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую определить, какое двузначное число пользователь ввел в окно
Edit, и вывести это число словами.
Вариант 6.24. Разработайте алгоритм, интерфейс пользователя и программу,
позволяющую определить сколько слов содержится в тексте, введенном в компонент RichEdit.
Вариант 6.25. Разработайте алгоритм, интерфейс пользователя и программу,
позволяющую определить частотность слов в тексте отображенном в компоненте
RichEdit.
112
Вариант 6.26. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую определить какую запись из букв и цифр ввел пользователь в окно Edit.
Вариант 6.27. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую определить частотность букв в предложении.
Вариант 6.28. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую заменить в слове из прописных букв все буквы кроме
первой на строчные.
Вариант 6.29. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую поменять в предложении первое и последнее слово местами.
Вариант 6.30. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую разбить сложносочиненное предложение на два простых
предложения.
6.4. Контрольные вопросы
1. Переменная символьного типа, её объявление и инициализация. Область использования переменного типа.
2. Строковая переменная типа Char. В чем ее отличие от переменной
символьного типа?
3. Способы объявления строковой переменной типа Char.
4. Как осуществляется доступ к отдельным символам строковой переменной.
5. Сколько байт содержится в строковой переменной и сколько значащих
символов?
6. Каким элементом заканчивается строковая переменная типа Char?
7. Какая функция используется для склеивания двух строк типа Char?
8. Поясните особенности склеивания строковых переменных типа Char.
9. Как скопировать в строку типа Char какой-либо текст.
10. Какая функция преобразует символы строки типа Char к верхнему регистру.
11. Как определить длину строки типа Char?
12. Объясните, в чем особенность строковых переменных типа AnsiString ?
13. Какие операции определены для строк типа AnsiString?
14. Как объявляется и инициализируется строка типа AnsiString?
15. Как преобразовать строку типа AnsiString в строку типа Char?
16. В каких случаях необходимо использовать строки типа AnsiString и
типа Char?
17. Как преобразовать строку типа Char в строку типа AnsiString?
18. Как склеить несколько строк типа AnsiString?
19. Как можно осуществить доступ к отдельным символам строки типа
AnsiString?
20. Что такое структуры в языке C++ Builder?
113
21. Как объявляются, определяются и используются структуры?
22. Чем структуры отличаются от классов.
23. Какие свойства объекта StringGrid определяют число столбцов и
строк.
24. Какое свойство используется для открытия доступа к редактированию
таблицы?
7. ЛАБОРАТОРНАЯ РАБОТА № 6
Тема: «Изучение среды C++ Builder. Применение в программах графических изображений».
Цель работы: Изучение возможностей среды программирования на
языке C++ Builder по разработке программ работы с графикой. Из учение
использования графических примитивов для создания графических изображений [1].
Задачи: разработать алгоритмы и программу на языке С++ Builder
решения задачи по созданию графических изображений с использованием
стандартных примитивов среды программирования С++ Builder.
Некоторые компоненты в C++ Builder имеют свойство Canvas (канва,
холст для рисования), представляющие собой область компонента, на которой
можно рисовать или отображать готовые изображения. Это свойство имеют
формы, графические компоненты Image, PaintPoint, Bitmap и многие другие.
Холст состоит из отдельных точек – пикселей. Пиксель – это наименьший элемент поверхности рисунка, с которым можно манипулировать. Положение пикселя на поверхности холста имеет координаты X и Y. В системе координат на
холсте значение X возрастает при перемещении слева направо, а значение координаты Y – при перемещении сверху вниз. Левая верхняя точка системы координат имеет координаты (0, 0), правая нижняя – координаты (ClientWidth,
ClientHeight). Доступ к отдельному пикселю осуществляется через свойство
Pixels, представляющую собой двумерный массив, элементы которого содержат
информацию о цвете (свойство TColor) точек холста.
Для того, чтобы на поверхности формы или компонента нарисовать линию, окружность, прямоугольник или другой графический элемент, необходимо к свойству Canvas применить соответствующий метод. Рисовать можно разными способами: первый вариант – рисование по пикселям, второй вариант –
рисование с помощью свойства Pen (перо).
При разработке программного продукта нередко возникает потребность
построить по результатам расчетов графики, диаграммы, украсить свое приложение какими-то иллюстрациями, пиктограммами либо предоставить пользователю возможность самостоятельно создавать графические изображения на
форме. C++ Builder предоставляет в распоряжение программиста большой
набор свойств и методов для работы с графикой.
114
7.1. Рисование по пикселям
Пример 7.1. Построить график функции y = sin (x). Для данной функции
xmin = 0, xmax = 4π, ymin = –1, ymax = 1.
Создайте проект и разместим на форме метки, командные кнопки и два
объекта Image1 и Image2, открыв страницу Additional на панели компонентов,
как показано на рис. 7.1.
Выделите оба окна Image и, вызвав контекстное меню, командой Size
установите размеры окон абсолютно одинаковыми.
Напишите код программы для события Click командной кнопки Нарисовать 1, показанный на листинге 7.1.
Листинг 7.1
Программа построения синусоиды методом рисования по пикселям
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
const float Pi= 3.14159;
float x, y; //координата функции
int px,py; // координата пиксела
for (px = 0; px <= Image1->Width; px++)
{
//x – координата точки функции, соответствующая пикселю с координатой px
x = px*4 * Pi/Image1->Width;
y = sin(x);
//py – координата пикселя, соответствующая координате y точки
функции
py = Image1 -> Height - (y + 1)* Image1 -> Height/2;
// устанавливается цвет пикселя для отображения на холсте
Image1->Canvas-> Pixels[px][py] = clBlack;
}
}
В этом коде вводятся переменные x и y, являющиеся значениями аргумента и функции, а также переменные px и py, являющиеся координатами пикселов, соответствующими x и y. Сама процедура состоит из цикла по всем значениям горизонтальной координаты пикселов px компонента Image1. Сначала
выбранное значение px пересчитывается в соответствующее значение x. Затем
производится вызов функции и определяется ее значение y. Это значение пересчитывается в вертикальную координату py. И в заключение цвет пикселя с координатами (px, py) устанавливается черным.
115
Рис. 7.1. Форма программы построения графика sin (x)
7.2. Рисование с помощью пера
У канвы имеется объекты Pen – перо и Brush –кисть. В свою очередь эти
объекты имеют ряд свойств и методов. Свойства объекта Pen (табл. 7.1) задают
цвет, толщину, тип линии и границы геометрической фигуры. Свойства объекта
Brush (табл. 7.2) задают способ закраски внутри замкнутой области (внутри
прямоугольника, внутри окружности, сектора).
Таблица 7.1
Свойства объекта Pen
Свойство
Color
Что определяет
Цвет линии
Width
Style
Толщина линии
Вид линии
Значения
clRed – красный, clGreen – зеленый, clBlue –
голубой, clBlack – черный и др., либо цифровой код, определяющий цвет.
Задается в пикселях
Ps Solid – сплошная линия
psDash – штриховая линия
psDot – пунктирная линия
psClear – нет линии
psInsideFrame – сплошная линия. Но при Width
> 1, допускающая цвета, отличные от палитры
Windows.
116
Свойства объекта Brush
Свойство
Color
Что определяет
Цвет
закрашивания
замкнутой
области
Style
Стиль
закрашивания
области
Таблица.7.2
Значения
clRed – красный,
clGreen – зеленый,
clBlue – голубой
clBlack – черный и др. либо цифровой код, определяющий цвет.
bsSolid – сплошная заливка.
Штриховка:
bsGorizontal – горизонтальная;
bsVertical – вертикальная;
bsFDiogonal – диагональная с наклоном линий
влево;
bsBDiogonal – диагональная с наклоном линий
вправо;
bsCross – в клетку;
bsDiagCross – диагональная клетка.
Таблица 7.3
Методы вычерчивания графических примитивов с помощью пера
Метод
LineTo (x, y)
Rectangle (x1,y1,x2,y2)
FillRect (x1,y1,x2,y2)
FrameRect(x1,y1,x2,y2)
RounRect(x1,y1,x2,y2)
Ellipse(x1,y1,x2,y2)
Are(x1,y1,x2,y2,x3,y3,x4,y4)
Chord(x1,y1,x2,y2,x3,y3,x4,y4)
Действия
Рисует линию из текущей точки в точку с установленными координатами
Рисует прямоугольник. (x1, y1, x2, y2) – координаты левого верхнего и нижнего правого углов
прямоугольника
Рисует закрашенный прямоугольник.
(x1, y1, x2, y2) – координаты диагональных углов
прямоугольника.
Рисует контур прямоугольника. Определяет координаты диагональных углов (x1, y1, x2, y2)
Рисует прямоугольник с округленными углами.
Рисует окружность или эллипс.
(x1, y1, x2, y2) – координаты диагональных углов
квадрата либо прямоугольника, в котором рисуется окружность, эллипс соответственно.
Рисует
дугу
окружности
или
эллипса.
x1, y1, x2, y2 – определяют эллипс (круг).
x3, y3, x4, y4 – задают начальную и конечную точки дуги.
Рисует замкнутую фигуру (сегмент), ограниченную дугой окружности или эллипса и хордой.
x1, y1, x2, y2 – определяют эллипс (круг).
x3, y3, x4, y4 – задают начальную и конечную точки дуги сегмента.
117
Продолжение таблицы 7.3
Метод
Pie(x1,y1,x2,y2,x3,y3,x4,y4)
Polyline (points, n)
Poligon (p, n)
Действия
Рисует
сектор
окружности
или
эллипса.
x1, y1, x2, y2 – определяют эллипс (круг).
x3,y3,x4,y4 – задают начальную и конечную точки
дуги сектора
Рисует ломаную линию. points – массив типа
TPoint. Каждый элемент массива представляет собой запись поля x и y, который содержит координаты точки перегиба ломанной; n – количество
звеньев ломанной.
Рисует замкнутую фигуру с кусочно-линейной
границей, p – массив записей типа TPoint, который
содержит координаты вершин многоугольника, n –
количество вершин.
У канвы имеется свойство PenPos. Это свойство определяет в координатах канвы текущую позицию пера. Перемещение пера без прорисовки линии,
т. е. изменение PenPos производится методом канвы MoveTo(x,y). Здесь x, y координаты точки, в которую перемещается перо. Эта текущая точка является исходной, от которой методом LineTo (x, y) можно провести линию в точку с координатами (x, y). При этом текущая точка перемещается в конечную точку линии и новый вызов метода LineTo будет проводить точку из этой новой текущей точки.
Пример 7.2. Программы рисования синусоиды методом Pen (Пера). Для формы
созданной в первом примере, напишите код программы, указанный в листинге 2 для
командной кнопки Нарисовать 2.
Листинг 7.2
void __fastcall TForm1::Button1Click(TObject *Sender)
{
const float Pi= 3.14159;
float x, y; //координаты точки функции
int px,py; // Координаты пикселя, соответствующие
Image2->Canvas->MoveTo(0,Image2->Height/2);
//точке с координатами x,y
for (px = 0; px <= Image2->Width; px++)
{
//x – координата, соответствующая пикселю
//с координатой px
x = px*4 * Pi/Image2->Width;
y = sin(x);
// y – координата пикселя, соответствующая координате y
py = Image2 -> Height - (y + 1)* Image2 -> Height/2;
// проводится линия на втором графике
Image2->Canvas->LineTo(px,py);
118
}
}
Откомпилируйте программу и выполните её. Легко видеть, что качество
двух одинаковых графиков сильно различается. На левом графике на крутых
участках сплошной линии нет, она распадается на отдельные точки – пиксели.
А правый график весь сплошной. Это показывает, что при равных условиях рисовать лучше пером, а не по пикселям.
В заключение данного раздела приведем пример построения графика
функции с осями координат.
Пример 7.3. Пусть вам требуется представить результаты расчетов функции y = a * sin (x)* exp (x / b) для различных значений a, b и аргумента х в графическом виде.
Исходными данными для решения задачи являются параметры функции:
x, a, b.
Выходные данные: значение y от x, отображенное в графической форме.
Выбор метода решения задачи
Как показали предыдущие примеры, лучшим способом рисования графика является рисование пером.
Алгоритм решения задачи
Рассмотрим, решение каких частных задач необходимо запрограммировать для построения графика.
1. Определить размеры области, на которой будет отображаться график.
Для этого необходимо определить максимальное и минимальное значение функции, в пределах которых будет изменяться амплитуда графика.
2. Определить положение осей координат.
3. Определить масштаб изображения, позволяющий построить график
таким образом, чтобы он занимал всю область формы, предназначенную для
вывода графика.
4. Выбрать толщину и цвет кривой, отображающий график.
5. Выбрать метод исправления возможных искажений графического
изображения.
6. Вычисление значений функции для заданных значений a и b и выбранного диапазона изменений аргумента x.
7. Нарисовать график в выделенной области формы.
Разработка интерфейса пользователя
Разместим на форме:
– информацию для пользователя о назначении программы и виде функции, для которой строится график в метках Label;
– командную кнопку Button EXIT для завершения работы программы. Вид
формы представлен на рис. 7.2.
119
Рис. 7.2. Интерфейс программы построения графика
Разработка кода программы
Для построения графика используется вся доступная область формы.
Причем, если во время работы программы пользователь изменит размер окна,
график будет выведен заново с учетом реальных размеров. Основу работы программы составляет функция Grafic1. Ее необходимо поместить в заголовочный
файл формы в раздел Private. После запуска программы функция по исходным
данным определяет область вывода графика, вычисляет коэффициенты масштабирования по осям и вычерчивает координатные оси. После вызова функции Fun (x) рисуется график.
Код программы приведен на листинге 7.3.
Следует обратить внимание, что данная программа строит график функций, принимающих как положительные, так и отрицательные значения. Для построения графиков функций, принимающих только положительные значения
или только отрицательные значения, программа должна быть доработана.
Листинг 7.3
Программа построения графика
#include <vcl.h>
#pragma hdrstop
#include "UnGrafic1.h"
#include "math.h"
//--------------------------------------------------------------------------#pragma package(smart_init)
#pragma resource "*.dfm"
120
TFGrafic1 *FGrafic1;
//--------------------------------------------------------------------------__fastcall TFGrafic1::TFGrafic1(TComponent* Owner)
: TForm(Owner)
{
}
//--------------------------------------------------------------------------float Fun(float x)
{
return 2* sin(x)*exp(x/5);
}
void __fastcall TFGrafic1::Button1Click(TObject *Sender)
{
FGrafic1->Close();
}
//--------------------------------------------------------------------------void Grafic1()
{
float x1,x2;// граница изменения аргумента функции
float y1,y2; // граница изменения значения функции
float x; // текущее значение координаты x
float y; // текущее значение координаты y
float dx; // приращение аргумента
int l, b; // левый верхний и нижний углы вывода функции
int w,h; // ширина и высота области вывода графика
float mx,my; // масштаб по оси x и y
int x0,y0; // начало координат
//область вывода графика
l = 10; // x – координата верхнего левого угла поля графика
b = Form1->ClientHeight-20; //y – координата левого нижнего угла поля
графика
h = Form1->ClientHeight-40; //высота
w = Form1->Width-20; // ширина
x1 = 0; // нижняя граница диапазона аргумента
x2 = 25; // верхняя граница диапазона аргумента
dx = 0.01; // шаг аргумента
// найдем максимальное и минимальное значение
//функции на отрезке [x1,x2]
x = x1 ;
y1 = Fun(x);
// минимум
x=x2;
y2 =Fun(x); // максимум
121
do {
y = Fun(x);
if (y <= y1) y1 = y;
if (y > y2) y2 = y;
x += dx;
} while(x <=x2);
//вычислим масштаб
my = (float)h/abs(y2 - y1);// масштаб по оси x
mx = w/abs(x2 - x1); );// масштаб по оси y
x0 = l + abs(x1* mx); //ось x
y0 = b-abs(y1*my);// //ось y
Canvas -> MoveTo(x0,b-h);
Canvas -> LineTo(x0,b);
Canvas -> MoveTo(1,y0);
Canvas -> LineTo(1+w,y0);
Canvas -> TextOutA(x0+5,b-h,FloatToStrF(y2,ffGeneral,6,3));
Canvas -> TextOutA(x0+5,b,FloatToStrF(y1,ffGeneral,6,3));
//построение графика
x = x1;
do{
y = Fun(x);
Canvas -> Pixels[x0+x*mx][y0 - y*my] = clRed;
// Canvas -> LineTo((x0 + x*mx),(y0 - y*my));
x =x + dx;
}while(x <= x2);
}
7.3. Рисование геометрических фигур
Пером можно рисовать не только прямые линии, но и фигуры. В табл. 7.1
– 7.3 приведены основные свойства и методы для объекта Pen. Объект позволяет закрашивать замкнутые области.
Пример 3. Нарисуйте и закрасьте программным способом фигуры, приведенные в табл. 7.3.
Для выполнения поставленной задачи, создайте проект и разместите на
форме объект Image и девять командных кнопок. Сделайте на них надписи, как
показано на рис. 7.2.
Для каждой командной кнопки напишите функцию обработки события
Click, как показано на листинге 3. Для построения фигур необходимо определить
значения координат основных точек фигур в соответствии с обозначениями, приведенными в табл. 7.3.
122
Рис. 7.3. Форма с отображением построенных фигур
Листинг программы построения примитивных геометрических фигур
приведен в листинге.
Задание. Напишите код программы, приведенный в листинге и напишите
комментарии к операторам программы в соответствии с тем, какие фигуры они
позволяют строить.
Листинг 7.4
Программа построения геометрических фигур
#include <vcl.h>
#pragma hdrstop
#include "UnRis2.h"
//--------------------------------------------------------------------------#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//--------------------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button1Click(TObject *Sender)
{
Image1->Canvas->Font->Style<<fsBold;
123
Image1->Canvas->Arc(10,10,90,90,90,50,10,50);
Image1->Canvas->TextOut(40,60,"Arc");
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button2Click(TObject *Sender)
{
Form1->Close();
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button3Click(TObject *Sender)
{
Image1->Canvas->Brush->Color= clRed;
Image1->Canvas->Chord(110,10,190,90,190,50,110,50);
Image1->Canvas->TextOut(135,60,"Chord");
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button4Click(TObject *Sender)
{
Image1->Canvas->Brush->Color= clBlue;
Image1->Canvas->Ellipse(210,10,290,50);
Image1->Canvas->TextOut(230,60,"Ellipse");
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button5Click(TObject *Sender)
{
Image1->Canvas->Brush->Color= clGreen;
Image1->Canvas->Pie(310,10,390,90,390,30,310,35);
Image1->Canvas->TextOut(340,60,"Pie");
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button6Click(TObject *Sender)
{
Image1->Canvas->Brush->Color=clAqua ;
points[0].x =30; points[0].y =150;
points[1].x =40; points[1].y =130;
points[2].x =40; points[2].y =140;
points[3].x =60; points[3].y =130;
points[4].x =170; points[4].y =150;
Image1->Canvas->Polygon(points,4);
Image1->Canvas->TextOut(30,170,"Polygon");
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button7Click(TObject *Sender)
124
{
points[0].x = 200; points[0].y = 100;
points[1].x = 220; points[1].y = 150;
points[2].x = 250; points[2].y = 120;
points[3].x = 280; points[3].y = 180;
points[4].x = 300; points[4].y = 150;
Image1->Canvas->Polyline(points,4);
Image1->Canvas->TextOut(250,170,"Polyline");
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button8Click(TObject *Sender)
{
Image1->Canvas->Brush->Color= clLime;
Image1->Canvas->Rectangle(330,170,480,100);
Image1->Canvas->TextOut(340,170,"Rectangle");
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button9Click(TObject *Sender)
{
Image1->Canvas->Brush->Color= clMaroon;
Image1->Canvas->RoundRect(500,170,580,100,20,20);
Image1->Canvas->TextOut(540,170,"RoundRect");
}
При разработке данной программы использовалась переменная points типа TPoint, объявление которой должно быть проведено в заголовочном модуле
формы. Для вывода текста на канву используется метод TextOut. Для закрашивания замкнутых областей используется объект Brush и его свойство Color , которому присваивается значение цвета заливки.
Пример 7.4. Создадим программу, рисующую олимпийскую символику.
Целью этого примера является освоение использования функций построения геометрических примитивов для построения более сложного р исунка.
Алгоритм решения данной задачи состоит в следующем:
1 Необходимо рассчитать, на каком расстоянии должны располагаться
центры колец и каковы должны быть диаметры колец, чтобы они пересекались.
2. Необходимо определить размеры окна (полотна), на котором будут р исоваться кольца.
3. Определить место и размеры размещения надписи.
Все эти расчеты можно провести с использованием линейки, карандаша и
циркуля, нарисовав макет. В качестве единиц измерения используются пиксели.
Готовая программа должна выводить на печать олимпийскую символику, показанную на рис. 7.4.
Листинг программы с подробными комментариями приводится ниже.
125
Рис. 7.4. Интерфейс пользователя программы, рисующей олимпийскую символику
Листинг 7.5
Программа, рисующая олимпийскую символику
#pragma package(smart_init)
#pragma resource "*.dfm"
TFOLIMP *FOLIMP;
//--------------------------------------------------------------------------__fastcall TFOLIMP::TFOLIMP(TComponent* Owner)
: TForm(Owner)
{
Canvas->Font->Name="Tahoma";
FOLIMP->Canvas->Font->Size=25;
}
//--------------------------------------------------------------------------void __fastcall TFOLIMP::Button1Click(TObject *Sender)
{
FOLIMP->Close();
}
//--------------------------------------------------------------------------void __fastcall TFOLIMP::FormPaint(TObject *Sender)
{
#define WB 140 //ширина полотнища
#define HB 160 //высота полотнища
#define D 100 //диаметр колец
int x,y;
AnsiString st ="Быстрее, выше, сильнее!";
126
// определим координаты левого верхнего угла флага
x =(ClientWidth-WB)/2;
y = (ClientHeight- HB)/2 - Canvas->Font->Size;
// полотнище
// выбираем цвет полотнища – белый
Canvas ->Brush->Color = (TColor)RGB(255,255,255);
//Рисуем прямоугольник полотнища
Canvas -> Rectangle(x-WB,y-HB/2,x+1.8*WB,y+HB);
int x1 = (ClientWidth- Canvas -> TextWidth(st))/2;
/*Чтобы область вывода текста не была закрашена цветом
фона, а также чтобы метод Ellipse рисовал окружность,
а не круг, значение свойства Brush-> Syle
должно быть равно bsClear */
Canvas -> Brush->Style= clWhite;
//bsClear;
//вывод девиза
Canvas -> TextOutA(x1,y+HB+6,st);
// ширина колец – 2 пикселя
Canvas -> Pen->Width=5;
//первый ряд колец
//*3,2*D – ширина области, занимаемая кольцами
первого ряда*/
x = x + (WB-3.2*D)/2;
y =y +(HB-1.8*D)/2;
Canvas -> Pen->Color= (TColor)RGB(0,0,225); //синий
Canvas -> Ellipse(x,y,x+D,y+D);
x= x +1.1*D;
Canvas -> Pen->Color= clBlack; //черный
Canvas -> Ellipse(x,y,x+D,y+D);
x= x +1.1*D;
Canvas -> Pen->Color= (TColor)RGB(225,0,0); //красный
Canvas -> Ellipse(x,y,x+D,y+D);
// рисуем второй ряд колец
x= x - D*0.55;
y = y + 0.6*D;
Canvas -> Pen->Color= (TColor)RGB(0,128,0); //зеленый
Canvas -> Ellipse(x,y,x+D,y+D);
x= x-D*1.1;
Canvas -> Pen->Color= (TColor)RGB(250,217,25);//желтый
Canvas -> Ellipse(x,y,x+D,y+D);
}
//--------------------------------------------------------------------------void __fastcall TFOLIMP::FormResize(TObject *Sender)
127
{
FOLIMP->Refresh();
}
//--------------------------------------------------------------------------Пример 7.5. Разработаем программу, рисующую на форме часы, показывающие текущее время с точностью до секунд.
Алгоритм разработки программы включает следующие частные задачи:
1. Нарисовать на форме циферблат часов с разметкой делений часов, минут и секунд.
2. Рассматривая часовую, минутную и секундную стрелки как вектора,
определить функции изменения углового положения векторов в зависимости от
текущего времени.
3. Определить функцию, рисующую положение стрелок на циферблате
через каждую секунду, отсчитываемую таймером, в зависимости от текущего
времени.
4. Определить функцию, стирающую стрелки в предшествующие моменты
времени. Вид формы с часами приведен на рис. 7.5.
Рис. 7.5. Интерфейс пользователя программы «Часы»
При написании кода программы для получения значений текущего времени использовалось системное время компьютера, а для перевода значений вр емени в формат часов, минут и секундную – функции класса TDateTime. Функции
рисования циферблата и стрелок для текущего времени – функция void
DrawClock() создавались с использованием метода рисования пером. Функция
определения углового положения концов векторов стрелок для текущего време-
128
ни используют стандартные математические функции, поэтому в заголовочный
файл формы должен быть включен файл math.h.
Для отсчета секундных интервалов времени применялся объект Timer, который включался при загрузке программы и через каждую секунду вызывал
функцию рисования стрелок. Для контроля правильности хода часов используется объект Edit.
Листинг 7.7
Программа часы
include <vcl.h>
#pragma hdrstop
#include "UOclok.h"
#include <DateUtils.hpp>
#include <math.h>
#include <Math.hpp>
//--------------------------------------------------------------------------#pragma package(smart_init)
#pragma resource "*.dfm"
TFOclok *FOclok;
//--------------------------------------------------------------------------int x0,y0; //центр циферблата
int x,y; //текущие координаты конца стрелок
TDateTime t;
int l,a;
//-------------------------------------------------------------------------//в конструкторе формы записывается все то, что должно быть создано
на форме при ее загрузке
__fastcall TFOclok::TFOclok(TComponent* Owner)
: TForm(Owner)
{
int ahr,amin,asec; //положение стрелок (угол)
TDateTime t;
//зададим размер формы
//в соответствии с размерами циферблата
ClientHeight =(R+80)*2;
ClientWidth=(R+80)*2;
x0=R+80;
y0=R+80;
t=Time();
// пуск таймера
Timer1->Interval=1000; // период сигнала от таймера – 1 сек
Timer1->Enabled = true;
}
//-----------------------------------------------------------------------------
129
//Функция определения координат векторов стрелок часов
void Vector(int X0,int Y0, int A,int l1)
{
//x0 – начало вектора
//a – угол между осью х и вектором
// l – длина вектора
int x,y; //координаты конца вектора
double const TORAD = 0.01745532; //коэффициент
//пересчета угла
// из градусов в радианы
FOclok -> Canvas->MoveTo(X0,Y0);
x = X0 + l1*cos(A*TORAD);
y = Y0 - l1*sin(A*TORAD);
FOclok ->Canvas ->LineTo (x,y);
}
//-----------------------------------------------------------------------------// Функция рисования стрелок
void DrawClock()
{
int ahr,amin,asec; //положение стрелок (угол)
TDateTime t;
t =Time();//текущее время
//стирание стрелок в предыдущий момент времени
// определение углового положения стрелок
// в предыдущий момент времени
ahr =90 -HourOfTheDay(t)*30-((MinuteOfTheHour(t)/12)*6+6);
amin =90-MinuteOfTheHour(t)*6+6;
asec =90-SecondOfTheMinute(t)*6+6;
//стирание часовой стрелки
FOclok ->Canvas->Pen->Color= clWhite;
FOclok ->Canvas ->Pen->Width = 3;
Vector(x0,y0,ahr,(R-30));
// стирание минутной стрелки
FOclok ->Canvas->Pen->Color=clWhite;
FOclok ->Canvas ->Pen->Width = 5;
Vector(x0,y0,(amin-1),(R-15));
//стирание секундной стрелки
FOclok ->Canvas-> Pen->Color=clWhite;
FOclok ->Canvas ->Pen->Width = 1;
Vector(x0,y0, asec,(R-7));
// новое положение стрелок
/* определить положение стрелок
Угол между метками (цифрами0 часов, например, 2 и 3 составляет 30
130
градусов, угол между метками минут – 6 градусов. Угол отсчитываем от метки
12 часов*/
ahr =90 -HourOfTheDay(t)*30-(MinuteOfTheHour(t)/12)*6;
amin =90-MinuteOfTheHour(t)*6;
asec =90-SecondOfTheMinute(t)*6;
//нарисовать стрелки
// часовую стрелку
FOclok ->Canvas ->Pen->Width = 3;
FOclok->Canvas->Pen->Color=clBlack;
Vector(x0,y0,ahr,R-30);
//минутную стрелку
FOclok ->Canvas ->Pen->Width=2;
FOclok-> Canvas->Pen-> Color = clRed;
Vector(x0,y0,amin,R-15);
//секундную стрелку
FOclok ->Canvas ->Pen->Width=1;
FOclok ->Canvas->Pen-> Color=clBlue;
Vector(x0,y0,asec,R-7);
}
//---------------------------------------------------------------------------// функция обработки выдачи интервалов отсчета таймера
void __fastcall TFOclok::Timer1Timer(TObject *Sender)
{
DrawClock(); // обращение к функции рисования стрелок
Edit1->Text= "";
t= Time();
Edit1->Text= t; // вывод текущего времени в текстовое окно
}
// функция обработки события командной кнопки «Exit»
void __fastcall TFOclok::Button1Click(TObject *Sender)
{
FOclok->Close();
}
//--------------------------------------------------------------------------// функция обработки события рисования
//на форме циферблата часов
void __fastcall TFOclok::FormPaint(TObject *Sender)
{
double TORAD = 0.01745532; //коэффициент пересчета угла
//из градусов в радианы
int x,y;
int a;
int h;
131
TBrushStyle bs;
TColor pc;
char pw;
bs = Canvas->Brush->Style;
pc= Canvas->Pen->Color;
Canvas->Pen->Width=2;
pw =Canvas->Pen->Width;
Canvas -> Brush->Style = bsClear;
Canvas -> Pen->Width ;
Canvas->Pen->Color = clBlack;
a = 0;
h = 3;
while (a<360)
{
x=x0 +R*cos(a*TORAD);
y=y0 -R*sin(a*TORAD);
FOclok->Canvas->MoveTo(x,y);
if ((a%30)==0)
{
Canvas->Ellipse(x-2,y-2,x+3,y+3); //рисование меток
//на циферблате
x = x0+(R+15)*cos(a*TORAD);
y = y0-(R+15)*sin(a*TORAD);
Canvas->TextOut(x-5,y-7,IntToStr(h)); //оцифровка
h--;
if(h==0)h=12;
}
else
Canvas->Ellipse(x-1,y-1,x+1,y+1);
a=a+6;
Canvas -> Brush->Style = bs;
Canvas -> Pen->Width =pw;
Canvas->Pen->Color = pc;
}
}
//---------------------------------------------------------При аккуратном и внимательном наборе кода программы, она будет работать и отображать текущее время. Код программы с подробнейшими комментариями, позволяющими уяснить основы создания движущихся объектов, приведен в листинге 7.6.
132
7.4. Задания для самостоятельного выполнения
1. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме график экспоненциальной функции.
2. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме оси декартовой системы координат с нанесенными на них делениями системы график функции.
3. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме график функции, описываемой квадратным
уравнением.
4. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме пирамиду из квадрата, круга и треугольника.
5. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме вращающийся круг.
6. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме вертикально расположенную цепочку из 5 колец.
7. Разработайте алгоритм, интерфейс пользователя и программу, по зволяющую отобразить на форме график функции.
8. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме движущийся круг.
9. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме оси декартовой системы координат с нанесением
на оси делений и оцифровки для заданного диапазонов изменения величин по
оси х и оси у.
10. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме вращающийся квадрат.
11. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме круг, сектора которого раскрашены в различные
цвета.
12. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме летящий круг по заданной траектории.
13. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме траекторию полет шара, брошенного под заданным углом
с заданной начальной скоростью.
14. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме график функции.
15. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме изображение пирамиды в аксонометрической
проекции.
16. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме график функции.
133
17. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме два разноцветных треугольника, стоящих вертикально, один на вершине другого вершиной вниз.
18. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме ломанную линию в виде ступенек лестницы.
19. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме пирамиду из стоящих друг на друге квадратов
уменьшающегося размера.
20. Разработайте алгоритм, интерфейс пользователя и пр ограмму,
позволяющую отобразить на форме лестницу из прямоугольников.
21. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме прямоугольник, разделенный диагоналями на
сектора, и закрасьте каждый сектор своим цветом.
22. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме вращающийся квадрат.
23. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме первый квадрант декартовой системы координат,
с нанесенными делениями и оцифровкой осей.
24. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме цепочку из разноцветных овалов (эллипсов).
25. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме заполнение формы небольшими разноцветными
кружочками (конфетти).
26. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме прыгающий шарик.
27. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме падающий квадрат.
28. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме флаг Российской Федерации.
29. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме пятиконечную звезду, окрашенную в красный
цвет.
30. Разработайте алгоритм, интерфейс пользователя и программу, позволяющую отобразить на форме шестиугольник, у которого каждый сектор окрашен в свой цвет.
7.5. Контрольные вопросы
1. Какие типы графических файлов поддерживает С++ Builder?
2. В чем различия при хранении информации в битовых матрицах и метафайлах?
3. Какие классы объектов определены для хранения графической инфо рмации?
134
4. Какой класс объектов может использоваться для хранения графической
информации любого формата?
5. Какие задачи по подготовке графических изображений можно решать с
помощью редактора изображений Image Editor?
6. Что представляет собой свойство Canvas и у каких объектов оно имеется?
7. В чем состоит сущность способа рисования по пикселам (Pixel)?
8. В чем состоит сущность способа рисования пером (Pen)?
9. Какие два метода используются для рисования пером и в чем их сущность?
10. Какой метод при рисовании пером используется для вывода текста?
11. Для чего используется свойство Brush (кисть) у свойства Canvas?
12. В чем сущность стирания изображения?
13. Какой метод используется для закрашивания замкнутой области?
14. Какие свойства формы определяют ее размер по ширине и по
длине?
ЗАКЛЮЧЕНИЕ
Лабораторный практикум по дисциплине "Компьютерные технологии"
поможет студентам, обучающихся по специальности 20.05.01 «Пожарная безопасность», и по направлению 20.03.01 «Техносферная безопасность», изучить
основы алгоритмизации и программирования научно-технических задач, языки
программирования высокого уровня, технологию обработки и отладки программ, современное программное обеспечение, методы решения типовых инженерных задач с их программной реализацией.
Темы лабораторных работ охватывают весь спектр возможностей языка высокого уровня C++ Builder, необходимых для программной реализации технич еских задач и составляют основу языка программирования. В учебном пособии
подробно излагаются следующие темы: изучение среды программирования с
программированием и отладкой простейших программ; разработка алгоритмов и
программ с использованием управляющих операторов; разработка программ с
использованием циклических структур; разработка алгоритмов и программ решения задач с использованием массивов; применение в программах символьных
и строковых переменных; изучение возможностей среды программирования на
языке C++ Builder по разработке программ работы с графикой.
Последовательное изучение студентами всех разделов лабораторного
практикума позволит создать необходимую основу для использования современных средств вычислительной техники и пакетов прикладных программ при
изучении студентами общетехнических и специальных дисциплин в течение
всего периода обучения.
135
Библиографический список
1. Рогачев, А.Ф. Лабораторный практикум по технологии программирования / А.Ф. Рогачев, Ю.Ю. Громов, Ю.С. Сербулов, С.А. Сазонова, И.Н.
Корнфельд, А.В. Лемешкин. - Воронеж, 2008.
2. Керниган, Б. Язык программирования Си / Б. Керниган, Д. Ритчи. – М.:
Финансы и статистика, 1992. – 271 с.
3. Электронная библиотечная система «КнигаФонд». [Электронный р есурс]. – (http://www.knigafund.ru/).
4. Электронная библиотечная система «IT-книга». [Электронный ресурс].
– (http://www.it-kniga.com/).
5. Электронная библиотечная система «ibooks.ru». [Электронный ресурс].
– (http://ibooks.ru/).
6. Университетская библиотека он-лайн. [Электронный ресурс]. –
(http://www.biblioclub.ru/).
7. Электронно-библиотечная система IQlib.ru – электронные учебники и
учебные пособия. [Электронный ресурс]. – (http://www.iqlib.ru/).
8. Автоматизированные системы управления и связь: учебн. пособие /
сост: С.А. Сазонова, С.А. Колодяжный, Е.А. Сушко; Воронежский ГАСУ. - Воронеж, 2014. - 168 с.
9. Надежность технических систем и техногенный риск: учебн. пособие /
сост: С.А. Сазонова, С.А. Колодяжный, Е.А. Сушко; Воронежский ГАСУ. - Воронеж, 2013. - 148 с.
10. Барковская, С.В. Интегрированный менеджмент XXI века: парадигма
безопасного и устойчивого (антикризисного) развития: монография / С.В. Барковская, Е.А. Жидко, В.П. Морозов, Л.Г. Попова. - Воронеж, 2011.
11. Жидко, Е.А. Проблемы организации управления экологической безопасностью на промышленном предприятии / Е.А. Жидко // Безопасность труда
в промышленности. - 2010. - № 8. - С. 38-42.
12. Жидко, Е.А. Формализация программы исследований информационной безопасности компании на основе инноваций / Е.А. Жидко, Л.Г. Попова //
Информация и безопасность. - 2012. - Т. 15. - № 4. - С. 471-478.
13. Жидко, Е.А. Динамика частиц золы в выбросах дымовых труб / Е.А.
Жидко, Е.М. Черных // Экология и промышленность России. - 2004. - № 7. - С.
38-39.
14. Жидко, Е.А. Управление техносферной безопасностью / Е.А. Жидко. Воронеж, 2013.
15. Жидко, Е.А. Теоретические основы проектирования и конструкции
жидкостных пылеулавливающих устройств / Е.А. Жидко, В.В. Колотушкин, Э.В.
Соловьева // Безопасность труда в промышленности. - 2004. - № 2. - С. 8-11.
16. Жидко, Е.А. Информационные риски в экологии XXI века: концепция
управления / Е.А. Жидко, Л.Г. Попова // Информация и безопасность. - 2010. Т. 13. - № 2. - С. 175-184.
136
17. Жидко, Е.А. Эмпирические методы измерения погрешностей при взаимосвязанном развитии внешней и внутренней среды хозяйствующих субъектов / Е.А. Жидко, В.К. Кирьянов // Научный журнал. Инженерные системы и
сооружения. - 2013. - № 4 (13). - С. 53-60.
18. Жидко, Е.А. Экологический менеджмент как фактор экологоэкономической устойчивости предприятия в условиях рынка / Е.А. Жидко //
Федеральное агентство по образованию, Гос. образовательное учреждение
высш. проф. образования Воронежский гос. архитектурно-строит. ун-т. Воронеж, 2009.
19. Попова, Л.Г. Информационный мониторинг безопасности и устойч ивости развития организации в XXI веке / Л.Г. Попова, С.В. Барковская, Е.А.
Жидко // Информация и безопасность. - 2009. - Т. 12. - № 4. - С. 497-518.
20. Иванова, И.А. Анализ критериев экологической опасности на асфальтобетонных заводах / И.А. Иванова, С.А. Колодяжный, В.Я. Манохин // Научный вестник Воронежского государственного архитектурно-строительного
университета. Строительство и архитектура. - 2009. - № 3. - С. 125-131.
21. Квасов, И.С. Статическое оценивание состояния трубопроводных систем на основе функционального эквивалентирования / И.С. Квасов, М.Я. Панов, С.А. Сазонова // Известия высших учебных заведений. Строительство. 2000, №4. - С. 100-105.
22. Квасов, И.С. Энергетическое эквивалентирование больших гидравлических систем жизнеобеспечения городов / И.С. Квасов, М.Я. Панов, В.И.
Щербаков, С.А. Сазонова // Известия высших учебных заведений. Строительство. - 2001.- № 4. - С. 85-90.
23. Квасов, И.С. Диагностика утечек в трубопроводных системах при неплотной манометрической съемке / И.С. Квасов, М.Я. Панов, С.А. Сазонова // Известия высших учебных заведений. Строительство. - 1999. - № 9. - С. 66-70.
24. Колодяжный, С.А. Решение задачи статического оценивания систем газоснабжения / С.А. Колодяжный, Е.А. Сушко, С.А. Сазонова, А.А. Седаев // Научный вестник Воронежского государственного архитектурно-строительного университета. Строительство и архитектура. - 2013. - № 4 (32). - С. 25-33.
25. Колодяжный, С.А. Применение энергетического эквивалентирования
для формирования граничных условий к модели анализа потокораспределения
системы теплоснабжения / С.А. Колодяжный, Е.А. Сушко, С.А. Сазонова //
Научный журнал. Инженерные системы и сооружения. - 2013. - № 3 (12). - С. 815.
26. Колодяжный, С.А. Решение задачи формирования нагруженного р езерва при управлении функционированием систем теплоснабжения / С.А. Колодяжный, Е.А. Сушко, С.А. Сазонова, К.А. Скляров // Научный журнал. Инженерные системы и сооружения. - 2013. - № 4 (13). - С. 8-15.
27. Колодяжный, С.А. Прикладные задачи безопасного функционирования систем теплоснабжения / С.А. Колодяжный, Е.А. Сушко, С.А. Сазонова,
К.А. Скляров // Научный журнал. Инженерные системы и сооружения. - 2014. -
137
№ 1 (14). - С. 8-17.
28. Колодяжный, С.А. Обеспечение безопасности функционирования систем газоснабжения при мониторинге технического состояния в условиях информационной неопределенности / С.А. Колодяжный, Е.А. Сушко, С.А.
Сазонова, К.А. Скляров // Научный вестник Воронежского государственного
архитектурно-строительного университета. Строительство и архитектура. 2014. - № 2 (34). - С. 132-140.
29. Колотушкин, В.В. Безопасность жизнедеятельности при эксплуатации
зданий и сооружений: учеб. пособ. / В.В. Колотушкин, С.Д. Николенко. - Воронеж: ВГАСУ. - 2009.
30. Манохин, В.Я. Эффективность улавливания гидрофобной пыли / В.Я.
Манохин, М.В. Манохин // Научный вестник Воронежского государственного
архитектурно-строительного университета. Серия: Физико-химические проблемы и высокие технологии строительного материаловедения. - 2008. - № 1. С. 151-154.
31. Манохин, В.Я. Нормы накопления ТБО, их состав и свойства / В.Я.
Манохин, И.А. Иванова, М.В. Манохин // Научный вестник Воронежского государственного архитектурно-строительного университета. Серия: Высокие технологии. Экология. - 2013. - № 1. - С. 21-27.
32. Михневич, И.В. К вопросу о защитных свойствах быстровозводимых
сооружений на основе пневмоопалубки / И.В. Михневич, С.Д. Николенко, В.А.
Попов // В сборнике: Пожарная безопасность: проблемы и перспективы: сборник статей по материалам III всероссийской научно-практической конференции
с международным участием, 20 сентября 2012 года. ФГБОУ ВПО Воронежский
институт противопожарной службы МЧС России. Воронеж, 2012. - С. 234-237.
33. Николенко, С.Д. Разработка конструкций пневматических опалубок /
С.Д. Николенко, И.В. Михневич // Научный журнал. Инженерные системы и
сооружения. - 2014.- № 2 (15). - С. 18-22.
34. Николенко, С.Д. Применение фибрового армирования в зданиях и с ооружениях, расположенных в сейсмоопасных районах / С.Д. Николенко // В
сборнике: Системы жизнеобеспечения и управления в чрезвычайных ситуациях: межвузовский сборник научных трудов. Воронежский государственный
технический университет, Международная академия наук экологии безопасности человека и природы; В.И. Федянин - ответственный редактор. Воронеж,
2006. - С. 38-46.
35. Николенко, С.Д. К вопросу экологической безопасности автомобильных дорог / С.Д. Николенко // Научный вестник Воронежского государственного архитектурно-строительного университета. Серия: Физико-химические проблемы и высокие технологии строительного материаловедения. - 2008. - № 1. С. 141-145.
36. Облиенко, А.В. Исследование эффективности установки сигнализаторов и газоанализаторов в производственных помещениях / А.В. Облиенко, О.Н.
Петрова, И.И. Переславцева, С.А. Колодяжный // Научный журнал. Инженер-
138
ные системы и сооружения. - 2010. - № 1. - С. 222-225.
37. Паршин, М.В. Учет зависимости коэффициента теплопотери от времени при прогнозировании динамики факторов пожара / М.В. Паршин, А.П.
Паршина // Научный журнал. Инженерные системы и сооружения. - 2011. № 2. - С. 50-54.
38. . Переславцева, И.И. Экспериментальные исследования времени эвакуации групп людей по лестничным клеткам зданий и сооружений / И.И. Переславцева, С.А. Яременко // Вестник гражданских инженеров. - 2013. - № 5 (40).
- С. 122-126.
39. Переславцева, И.И. Прогнозирование разрушений аммиакопроводов
при возникновении чрезвычайных ситуаций / И.И. Переславцева, В.Д. Касенков, Д.Ю. Попков, Е.А. Павлова // Научный журнал. Инженерные системы и
сооружения. - 2012. - № 3 (8). - С. 78-86.
40. Сазонова, С.А. Разработка методов и алгоритмов технической диагностики систем газоснабжения: автореф. дис. ... канд. техн. наук: защищена
18.05.2000: утв. 13.10.2000 / С.А. Сазонова. - Воронеж, 2000. - 15 с.
41. Сазонова, С.А. Статическое оценивание состояния систем теплоснабжения в условиях информационной неопределенности / С.А. Сазонова // Моделирование систем и информационные технологии: сб. науч. тр. М-во образования Российской Федерации, [редкол.: Львович И. Я. (гл. ред.) и др.]. – М., 2005.
- С. 128-132.
42. Сазонова, С.А. Разработка модели анализа невозмущенного состояния
системы теплоснабжения при установившемся потокораспределении / С.А. Сазонова // Интеллектуализация управления в социальных и экономических системах. Труды Всероссийской конференции. 2006. С. 57-58.
43. Сазонова, С.А. Разработка модели анализа потокораспределения во змущенного состояния системы теплоснабжения / С.А. Сазонова // Моделирование систем и информационные технологии. Сб. науч. тр. - Воронеж, 2007. - С.
52-55.
44. Сазонова, С.А. Разработка модели транспортного резервирования для
функционирующих систем теплоснабжения / С.А. Сазонова // Вестник Воронежского института высоких технологий. – 2007. – № 2-1. - С. 48 - 51.
45. Сазонова, С.А. Разработка модели структурного резервирования для
функционирующих систем теплоснабжения / С.А. Сазонова // Вестник Воронежского института высоких технологий. – 2008. – № 3. - С. 82 - 86.
46. Сазонова, С.А. Структурное резервирование систем теплоснабжения /
С.А. Сазонова // Вестник Воронежского государственного технического университета. - 2010. - Т. 6. - № 12. - С. 179-183.
47. Сазонова, С.А. Результаты вычислительного эксперимента по апробации метода решения задачи статического оценивания для систем теплоснабжения / С.А. Сазонова // Вестник Воронежского института высоких технологий. 2010. - № 6. – С. 93-99.
48. Сазонова, С.А. Результаты вычислительного эксперимента по апроба-
139
ции математических моделей анализа потокораспределения для систем теплоснабжения / С.А. Сазонова // Вестник Воронежского института высоких технологий. - 2010. - № 6. – С. 99- 104.
49. Сазонова, С.А. Решение задачи статического оценивания систем теплоснабжения / С.А. Сазонова // Вестник Воронежского государственного технического университета. - 2011. - Т. 7. - № 5. - С. 43-46.
50. Сазонова, С.А. Итоги разработок математических моделей анализа
потокораспределения для систем теплоснабжения / С.А. Сазонова // Вестник
Воронежского государственного технического университета. - 2011. - Т. 7. № 5. - С. 68-71.
51. Сазонова, С.А. Транспортное резервирование систем теплоснабжения
/ С.А. Сазонова // Вестник Воронежского государственного технического университета. - 2011. - Т. 7. - № 2. - С. 99-101.
52. Сазонова, С.А. Разработка метода дистанционного обнаружения утечек в системах газоснабжения / С.А. Сазонова // Вестник Воронежского государственного технического университета. - 2011. - Т. 7. - № 11. - С. 119-121.
53. Сазонова, С.А. Решение задачи статического оценивания систем газоснабжения / С.А. Сазонова // Вестник Воронежского государственного технического университета. - 2011. - Т. 7. - № 11. - С. 139-141.
54. Ткаченко, А.Н. Теоретическая оценка распределения фибр в дисперсно-армированных бетонах / А.Н. Ткаченко, С.Д. Николенко, Д.В. Федулов //
Научный вестник Воронежского государственного архитектурно-строительного
университета. Строительство и архитектура. - Воронеж: ВГАСУ, 2010. - №4. С. 54-58.
55. Kolodyazhny S.A., Sushko Ye.A., Sazonova S.A., Sedayev A.A. Static estimation of gas supply systems // Scientific Herald of the Voronezh State University
of Architecture and Civil Engineering. Construction and Architecture. 2014.
№ 2 (22). С. 15-26.
56. Tkachenko, A.N. Theoretical estimation of fiber distribution in fiber reinforced concretes / A.N. Tkachenko, S.D. Nikolenko, D.V. Fedulov // Scientific Herald of the Voronezh State University of Architecture and Civil Engineering. Construction and Architecture. - 2011. - № 3. - С. 36-41.
Приложение
Математические функции
При работе с математическими функциями надо иметь ввиду, что файлы
math.h и Math.hpp в C++ Builder автоматически не подключаются к модулю
приложения. Поэтому для использования описанных в этих файлах функций
необходимо вручную вводить директивы в раздел, предшествующий разделу
описания классов заголовочного файла:
# include <math.h>
# include <Math.hpp>.
140
Таблица П.1
Константы, используемые в математических выражениях
Константа
M_PI
M_PI_2
M_PI_4
M_1_PI
M_1_SQRTPI
M_2_PI
M_1_SQRTPI
M_E
M_LN10
M_LN2
M_LOG10E
M_LOG2E
M_SQRT2
M_SQRT_2
Описание
Число π
π/2
π/4
1/ π
Корень квадратный из 1/ π
2/ π
2/корень квадратный из π
Число e
ln(10) – логарифм натуральный от 10
ln(2) – логарифм натуральный от 2
log10 (e) – логарифм десятичный от e
log2 (e) логарифм по основанию
2 от e
Корень квадратный из 2
Корень из 2 деленный на 2
Значение
Тригонометрические функции
Функция
acos
asin
atan
cos
sin
tan
double
double
double
double
double
double
Синтаксис
acos (double x)
asin (double x)
atan (double x)
cos (double x)
sin (double x)
tan (double x)
Описание
Арккосинус
Арксинус
Арктангенс
Косинус
Синус
Тангенс
Арифметические и алгебраические функции
Функция
abs
fabs
ceil
div
exp
fmod
log
log10
max
min
pow
sqrt
Таблица П.2
Синтаксис
Int abs(int x)
double fabs(double x)
double ceil(double x)
div (int number, int denom)
exp double exp (double x)
double fmod (double x/y)
double log (double x)
double log10 (double x)
max (a,b)
min(a,b)
double pow (double x,
double y)
double sqrt(double x)
Таблица П.3
Описание
Абсолютное значение
Абсолютное значение
Округление вверх
Целочисленное деление
экспонента
Остаток от деления
Натуральный логарифм
Десятичный логарифм
Максимальное число
Минимальное число
Степень y числа x x y
Корень квадратный
из числа x
141
Таблица П.4
Функции перерасчета градусы-радианы
DegToRad
Extended DegToRad
(Extended x)
RadToDeg
Extended RadToDeg
(Extended x)
1.
2.
3.
4.
5.
Вычисляет угол в
радианах по его
значению в градусах
Вычисляет угол в
градусах по его
значению в радианах
ОГЛАВЛЕНИЕ
Введение ......................................................................................
ОСНОВНЫЕ ПОНЯТИЯ ЯЗЫКА С/С++ BUILDER...............
1.1. C++ Builder система визуального
объектно-ориентированного программирования....................
1.2. Общие сведения о программах на C++ Builder.................
1.3. Области видимости переменных и функций
в программах на C++ Builder.....................................................
1.4. Основные рекомендации для разработки программ.........
ЛАБОРАТОРНАЯ РАБОТА № 1..............................................
2.1. Разработка алгоритма решения задачи............................
2.2. Разработка проекта на языке С++Bilder.........................
2.3. Разработка интерфейса пользователя.............................
2.4. Выбор визуальных объектов для стартовой формы........
2.5. Задание свойств объектов..................................................
2.6. Написание кода программы.................................................
2.7. Сохранение проекта.............................................................
2.8. Компиляция программы.......................................................
2.9. Отладка и тестирование программ...............................
2.10. Задания для лабораторной работы № 1..........................
2.11. Контрольные вопросы.......................................................
ЛАБОРАТОРНАЯ РАБОТА № 2..............................................
3.1. Теоретический материал....................................................
3.2. Примеры решения задач......................................................
3.3. Задания для лабораторной работы № 2............................
3.4. Контрольные вопросы.........................................................
ЛАБОРАТОРНАЯ РАБОТА № 3.............................................
4.1. Теоретические сведения.......................................................
4.2. Задания для лабораторной работы № 3............................
4.3. Контрольные вопросы.........................................................
ЛАБОРАТОРНАЯ РАБОТА № 4.............................................
5.1. Теоретические сведения............................................................
5.2. Задания для самостоятельного выполнения.....................
142
3
4
4
6
10
11
13
14
16
16
17
18
23
27
28
28
32
35
36
36
44
53
56
57
57
66
70
71
71
89
5.3. Контрольные вопросы.........................................................
6. ЛАБОРАТОРНАЯ РАБОТА № 5..............................................
6.1. Теоретический материал....................................................
6.2. Структуры в языке C++ Builder........................................
6.3. Задания для самостоятельной работы.............................
6.4. Контрольные вопросы.........................................................
7. ЛАБОРАТОРНАЯ РАБОТА № 6..............................................
7.1. Рисование по пикселям.........................................................
7.2. Рисование с помощью пера..................................................
7.3. Рисование геометрических фигур.......................................
7.4. Задания для самостоятельного выполнения.....................
7.5. Контрольные вопросы.........................................................
Заключение...................................................................................
Библиографический список.........................................................
Приложение.................................................................................
92
92
92
103
111
113
114
115
116
122
133
134
135
136
140
Учебное издание
КОМПЬЮТЕРНЫЕ ТЕХНОЛОГИИ
Лабораторный практикум
Составители: Светлана Анатольевна Сазонова
Сергей Александрович Колодяжный
Елена Анатольевна Сушко
Отпечатано в авторской редакции
Подп. в печать 12.05.. 2015. Формат 60х84 1/16. Уч.-изд. л. 8,9. Усл.-печ. л. 9,0.
Бумага писчая. Тираж 100 экз. Заказ №
.
Отпечатано: отдел оперативной полиграфии издательства
учебной литературы и учебно-методических пособий Воронежского ГАСУ
394006 Воронеж, ул. 20-летия Октября,84
143
Документ
Категория
Без категории
Просмотров
21
Размер файла
1 573 Кб
Теги
практикум, технология, 564, компьютерные, сазонова, лабораторная
1/--страниц
Пожаловаться на содержимое документа