Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по Технологии разработки ПО 2005.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
833.54 Кб
Скачать

97

Министерство образования и науки Российской Федерации

Московский государственный университет дизайна и технологии

Секция САПР

Курс лекций и семинаров по дисциплине

"Технология разработки ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ"

для студентов, обучающихся по специальности

220300 - Системы автоматизированного проектирования

Курс: 2

Семестр: 4

Составил:

к.т.н., ассистент секции САПР

Семёнов А.А.

Москва  2004-2005

Лекция 1 (5,5 стр.)

Список литературы, рекомендуемой для самостоятельного изучения:

  1. Страуструп Б. "Язык программирования С++". – СПб.: БИНОМ, 1999

  2. Павловская Т.А. "С/С++. Программирование на языке высокого уровня". – СПб.: Питер, 2003

  3. Лафоре Р. "Объектно-ориентированное программирование в С++", 4-е изд. – СПб.: Питер, 2004

  4. Савитч У. "Язык С++. Курс объектно-ориентированного программирования", 3-е изд. – М.: Вильямс, 2001

  5. Архангельский А.Я. "Программирование в С++Builder 6". – М.: БИНОМ, 2003

  6. Седжвик Р. "Фундаментальные алгоритмы на С++. Анализ/Структуры данных/Сортировка/Поиск". – СПб.: ДиаСофтЮП, 2002

  7. Страуструп Б. "Дизайн и эволюция языка С++". – М.: ДМК, 2000

  8. Вирт Н. "Алгоритмы + структуры данных = программы". – М.: Мир, 1985

  9. Мейерс С. "Эффективное использование С++". – М.: ДМК, 2000

Тема 1. Введение в интегрированную среду разработки С++Builder

Объектно-ориентированное программирование (ООП) – это современный подход к построению сложных программ и систем. Любое Windows-приложение содержит множество кнопок, разделов меню, списков и т.п. Всё это объекты, которые ждут каких-то событий: нажатия кнопок, перемещения курсора и т.д. Когда происходит подобное событие, объект получает сообщение об этом и реагирует. Таким образом, объектно-ориентированная программа – это совокупность объектов и способов их взаимодействия. Объект можно определить как совокупность свойств и методов, а также событий, на которые он может реагировать.

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

Появление визуального программирования явилось толчком в развитии CASE-технологии (технологии автоматизированного проектирования ПО). Фактически, проектирование в ИСР С++Builder сводится к размещению компонентов на форме, заданию их свойств и написанию кода обработчиков событий. Типы объектов и, в частности, компонентов библиотек С++Builder оформляются в виде классов. Классы – это типы, определяемые пользователем. В классах описываются свойства объекта, его методы и события, на которые он может реагировать. Важное свойство классов – наследование. Новый класс может наследовать свойства, методы и события своего родительского класса, т.е. того класса, на основе которого он создаётся.

Тема 2. Технологии программирования

На сегодняшний день существуют следующие основные технологии программирования:

  • структурное программирование, которое подразделяется на линейное, процедурное и модульное программирование;

  • объектно-ориентированное программирование.

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

Типичным примером процедурного программирования является задача вычисления факториала числа. Составим консольное приложение:

// n!=1*2*…*n; 0!=1, 1!=1

#include <iostream.h>

int factorial(int n);

int main(int argc, char* argv[])

{

int resultF, ch;

cout << " Введите число: ";

cin >> ch;

resultF = factorial(ch);

cout << "\n Факториал числа " << ch << " равен " << resultF;

return 0;

}

int factorial(int n)

{

int resultat = 1;

while (n > 0)

{

resultat = resultat * n;

n--;

}

return resultat;

}

Теперь составим эквивалентное визуальное приложение, позволяющее вычислять факториал числа:

1) File/New/Application

2) Button, Edit, Panel

3) Button1 | Events/OnClick:

int faktorial(int n)

{

int resultat = 1;

while (n > 0)

{

resultat = resultat * n;

n--;

}

return resultat;

}

void __fastcall TForm1::Button1Click(TObject *Sender)

{

Panel1->Caption = Edit1->Text + "! = " +

IntToStr(faktorial(StrToInt(Edit1->Text)));

}

А теперь приведем эквивалентную визуальную программу, написанную по линейной технологии:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

int resultat = 1;

int n;

n = StrToInt(Edit1->Text);

while (n > 0)

{

resultat = resultat * n;

n--;

}

Panel1->Caption = Edit1->Text + "! = " + IntToStr(resultat);

}

В больших по объёму программах использование функций является первым шагом к повышению степени абстракции программы и ведёт к упрощению её структуры. Следующим шагом в повышении уровня абстракции программы является группировка функций и связанных с ними данных в отдельные файлы (модули), компилируемые раздельно. Получившиеся в результате компиляции объектные модули объединяются в исполняемую программу с помощью компоновщика (Project/Build Project). Непростая задача разделения программы на обособленные части должна решаться на этапе проектирования программы.

Разбиение на модули уменьшает время перекомпиляции и облегчает процесс отладки, скрывая несущественные детали за интерфейсом модуля. Скрытие деталей реализации называется инкапсуляцией. Инкапсуляция является ключевой идеей как структурного, так и объектно-ориентированного программирования. Пример инкапсуляции – помещение фрагмента кода в функцию и передача всех необходимых ей данных в качестве параметров. Чтобы использовать такую функцию, требуется знать только её интерфейс, определяемый заголовком (тип возвращаемого значения, имя и типы параметров). Интерфейсом модуля являются заголовки всех функций и описания доступных извне типов, переменных и констант. Модульность в языке С++ поддерживается с помощью директив препроцессора, пространств имён, классов памяти, исключений и раздельной компиляции.

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

Перечислим общепринятые правила кодирования и документирования программы.

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

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

  • Необходимо тщательно подбирать имена переменных.

  • Локальные переменные предпочтительнее глобальных.

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

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

  • Выходные параметры функции предпочтительнее передавать по адресу, а не по ссылке.

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

  • Следует избегать использования в программе чисел в явном виде. Нужно применять константы, имеющие осмысленные имена и заданные через const или enum.

  • При использовании циклов желательно стремиться объединять инициализацию, проверку условия выхода и приращение в одном месте.

Рассмотрим основные этапы создания крупных программ.

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

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

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

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

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

Д/З

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

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

Семинар 1 (5 стр.)

Тема 1. Основные аспекты работы в ИСР С++Builder

Начнём с проверки 1-ого задания на дом: Составить программу вычисления факториала числа с использованием цикла for. Вычисление факториала реализовать в виде функции. Программа может быть написана как в консольном, так и в визуальном исполнении.

// Вычисление факториала с использованием цикла For:

int factorial(int N)

{

int result = 1;

for (int i = 1; i <= N; i++) result = result * i;

return result;

}

void __fastcall TForm1::Button2Click(TObject *Sender)

{

Panel2->Caption = Edit1->Text + "! = " + IntToStr(factorial(StrToInt(Edit1->Text)));

}

На протяжении прошлого семестра в основном вы использовали ИСР С++Builder для создания относительно простых консольных приложений. В этом семестре мы наряду с разработкой консольных приложений будем создавать также визуальные Windows-приложения … В связи с этим, рассмотрим вкратце основной инструментарий ИСР С++Builder.

ИСР содержит в себе редактор кодов, отладчик, инструментальные панели, редактор изображений, палитру компонентов и т.д. Ниже полосы главного меню расположены две инструментальные панели, одна из которых содержит палитру компонентов. В основном поле (слева) имеется окно "Инспектор объектов" (Object Inspector). "Инспектор Объектов" – это основной инструмент, с помощью которого вы будете задавать свойства компонентов и обработчики событий. По центру располагается окно пустой формы, готовой для переноса на неё компонентов. Под формой обычно расположено окно "Редактора Кодов".

Рассмотрим пример создания простого визуального приложения, позволяющего вводить в окна редактирования два числа и после нажатия кнопки выводить результат их произведения и деления на панель:

  1. Edit1, Edit2, Button1, Button2, Panel1

  2. Button1 | Events/OnClick :

// Умножение

void __fastcall TForm1::Button1Click(TObject *Sender)

{

Panel1->Caption = Edit1->Text + " * " + Edit2->Text + " = " +

FloatToStr(StrToFloat(Edit1->Text) * StrToFloat(Edit2->Text));

}

//---------------------------------------------------------------------------

  1. Button2/Name = Delenie

  2. Button2 | Events/OnClick :

// Деление

void __fastcall TForm1::DelenieClick(TObject *Sender)

{

Panel1->Caption = Edit1->Text + " / " + Edit2->Text + " = " +

FloatToStr(StrToFloat(Edit1->Text) / StrToFloat(Edit2->Text));

}

//---------------------------------------------------------------------------

5) Напишем обработчик события OnKeyPress для комп. Edit2, позволяющий исключить возможность деления на ноль. Edit2 | Events/OnKeyPress :

void __fastcall TForm1::Edit2KeyPress(TObject *Sender, char &Key)

{

if(Key == '0') Delenie->Enabled = false;

else Delenie->Enabled = true;

}

Рассмотрим важнейшие файлы, которые образуются после создания приложения:

  • головной файл проекта project.cpp;

  • файл опций проекта project.bpr;

  • файл ресурсов проекта project.res;

  • файл реализации модуля unit.cpp;

  • заголовочный файл модуля unit.h;

  • файл формы unit.dfm;

  • исполняемый файл project.exe.

C++Builder не допускает одинаковых имён модулей и проектов, т.к. файл модуля и головной файл проекта имеют одинаковое расширение *.cpp. При сохранении целесообразно задавать имена файлов проекта и модуля следующим образом:

  • файл проекта – arifmetika;

  • файл модуля – U_ arifmetika.

Проведём краткий обзор компонентов. Рассмотрим вначале компоненты ввода и отображения текстовой информации, которые находятся на страницах Standard, Additional, Win32. Для отображения различных надписей на форме используются в основном компоненты Label, StaticText, Panel. Первые два из этих компонентов – метки, специально предназначенные для отображения текстов. Панель предназначена как для компоновки компонентов в окне формы, так и для вывода текстов. Тексты, отображаемые в перечисленных компонентах, определяются значением их свойства Caption. Его можно устанавливать в процессе проектирования или программно. Компоненты StaticText, Panel имеют свойство BorderStyle, определяющее форму бордюра. Компонент Panel имеет ещё свойства BevelInner, BevelOuter, Border…, которые позволяют изменять оформление надписи и формы панели. В панели размещение надписи в несколько строк невозможно, а в StaticText перенос длинного текста осуществляется автоматически, если значение AutoSize=false и размер компонента достаточен для размещения нескольких строк.

Для ввода данных используются окна редактирования Edit, MaskEdit.

Для выполнения каких-то действий используются кнопки, индикаторы и управляющие элементы, расположенные на страницах Standard, Additional, Win32. В качестве управляющих кнопок используются обычно Button или, если желательно иметь на кнопке пиктограмму – BitBtn. Кнопки SpeedButton применяются в качестве быстрых кнопок для построения инструментальных панелей, в которых требуется фиксация нажатого состояния. Компонент RadioGrup применяется для формирования группы регулярно размещённых радиокнопок, из которых может быть включена только одна. Если регулярное размещение радиокнопок нежелательно, то компоненты RadioButton можно расположить на панели GroupBox. Для введения в приложение различных опций, которые пользователь может включать и выключать, используются индикаторы CheckBox.

Основное, с точки зрения внешнего вида, свойство кнопки – Caption (надпись). В надписях кнопок можно предусматривать использование клавиш ускоренного доступа. Например: Button1/Caption = &Выполнить. На кнопке появится надпись Выполнить, а нажатие клавиш Alt+B будет эквивалентно щелчку на кнопке.

Основное событие любой кнопки – OnClick, возникающее при щелчке на ней. Именно в обработчике этого события записываются операторы, которые должны выполняться при щелчке пользователя на кнопке.

Из методов, присущих кнопкам, следует отметить метод Click. Его выполнение эквивалентно щелчку на кнопке, т.е. вызывает событие кнопки OnClick. Пусть, например, вы хотите, чтобы при нажатии пользователем клавиши "С" или "с" в любой момент работы с приложением выполнялись операции, предусмотренные в обработчике события OnClick кнопки Button1. Поскольку неизвестно, какой компонент будет находиться в фокусе в момент этого события, надо перехватить его на уровне формы: а) Form1/KeyPreview=true; б) Form1 | Events/OnKeyPress: if ((Key == 'C') || (Key == 'с')) Button1->Click(); .

Изображение на кнопках BitBtn, SpeedButton задаётся свойством Glyph. Положение изображения по отношению к надписи определяется свойством Layout.