Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ПИ методичка 1-5

.pdf
Скачиваний:
9
Добавлен:
08.04.2015
Размер:
1.64 Mб
Скачать

Учебное пособие по дисциплине “Программная инженерия”

1. Подпрограммы и модульное программирование

Время выполнения лаб. работы — 2 аудиторных часа

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

зиции.

Структурный подход требует представления задачи в виде иерархии подзадач простейшей структуры, таким образом, проектирование осуществляется “сверху-вниз” (от общего к частному).

Замечание

Поддержка принципов структурного программирования была заложена в основу так называемых процедурных языков программирования. Как правило, они включали основные «структурные» операторы передачи управления, поддерживали вложение подпрограмм, локализацию и ограничение области «видимости» данных. Среди наиболее известных языков этой группы стоит назвать PL/1, ALGOL-68, Pascal, С.

Модульное программирование предполагает выделение групп подпрограмм, использующих одни и те же глобальные данные в отдельно компилируемые модули (библиотеки подпрограмм).

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

(рис. 1.1).

Основная программа

Глобальные

данные

Модуль1

Модуль K

Данные

Данные

Данные

Данные

Данные

Данные

1

N

1

N

Подпрограммы с

Подпрограммы с

локальными данными

локальными данными

Рисунок 1.1 — Архитектура программы, состоящей из модулей

1

Учебное пособие по дисциплине “Программная инженерия”

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

Задание

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

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

Вариант 1. Разработать программный модуль “МАТЕМАТИКА” предоставляющий следующий функционал:

сравнение двух действительных чисел с возвратом наибольшего из них;

сравнение трёх действительных чисел с возвратом наибольшего из них;

сравнение четырёх действительных чисел с возвратом наибольшего из них;

расчёт выражения ( + )2;

расчёт квадратного уравнения 2 + + = 0;

Вариант 2. Разработать программный модуль “ПИФАГОР” предоставляющий следующий функционал:

расчёт гипотенузы C по значениям катетов A и B;

расчёт sin a по значениям A и C;

расчёт cos b по значениям A и C;

 

b

расчёт sin b по значениям B и C;

C

 

 

A

расчёт cos a по значениям B и C;

 

 

 

 

 

 

 

 

 

расчёт значения угла a значениям A и C;

 

 

 

 

расчёт значения угла b значениям A и C;

a

 

 

 

расчёт значения угла a значениям B и C;

 

 

 

 

 

 

 

 

 

 

 

расчёт значения угла b значениям B и C;

 

B

Вариант 3. Разработать программный модуль “ПЛОЩАДЬ ФИГУРЫ” предоставляющий следующий функционал:

расчёт площади S прямоугольного треугольника по значениям катетов A и B;

расчёт площади S квадрата по размеру его стороны A;

расчёт площади S прямоугольника по размеру его сторон A и B;

расчёт площади S круга ( = 2) по размеру его радиуса R.

2

Учебное пособие по дисциплине “Программная инженерия”

Вариант 4. Разработать программный модуль “ПЕРИМЕТР ФИГУРЫ” предоставляющий следующий функционал:

расчёт периметра P прямоугольного треугольника по значениям катетов A и B;

расчёт периметра P квадрата по размеру его стороны A;

расчёт периметра P прямоугольника по размеру его сторон A и B;

расчёт периметра P круга ( = 2) по размеру его радиуса R.

Вариант 5. Разработать программный модуль “МАССИВ” работающий с одномерным массивом целых чисел A размерностью N элементов предоставляющий следующий функционал:

расчёт суммы элементов одномерного массива;

возврат индекса наименьшего элемента массива;

возврат индекса и значения наименьшего элемента массива;

возврат индекса наибольшего элемента массива;

возврат индекса и значения наибольшего элемента массива.

Вариант 6. Разработать программный модуль “ПЕРЕСЧЁТ ВЕЛИЧИН” предоставляющий следующий функционал:

пересчёт значения скорости км/ч в м/с;

пересчёт значения скорости м/с в км/ч;

пересчёт значения угла в градусах в угол, выраженный в радианах;

пересчёт значения угла в радианах в угол, выраженный в градусы;

пересчёт значения времени в секундах в формат ЧЧ:ММ:СС;

пересчёт времени в формате ЧЧ:ММ:СС в секунды.

Вариант 7. Разработать программный модуль “ПЕРЕВОД СИМВОЛОВ” предоставляющий следующий функционал:

возвратить числовое значение соответствующее заданному символу (таблица ANSI);

возвратить символ по его числовому значению;

преобразовать латинский символ в кириллический по принципу размещения символов на кнопках клавиатуры (Q — Й, W — Ц, E — У, и т.д.);

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

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

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

ВНИМАНИЕ!

При выполнении задания запрещается задействовать библиотечные процедуры и функции.

3

Учебное пособие по дисциплине “Программная инженерия”

2. Средства описания структурных алгоритмов

Время выполнения лаб. работы — 4 аудиторных часа

Различают три вида вычислительного процесса, реализуемого программами:

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

2.Разветвленная структура процесса вычислений предполагает, что конкретная последовательность операций зависит от значений одной или нескольких переменных

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

Именно для изображения схем алгоритмов таких программ в свое время был разработан ГОСТ 19.701-90, согласно которому каждой группе действий ставится в соответствие специальный блок (табл. 2.1).

 

 

 

 

 

 

Таблица 2.1. — Основные обозначения ГОСТ 19.701-90

 

 

 

 

 

 

 

 

Название

 

 

Обозначение

Назначение блока

Терминатор

 

 

 

Действие

Начало, завершение программы или под-

 

 

 

 

программы

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Процесс

 

 

 

 

 

 

Обработка данных (вычисления, пересылки)

 

 

 

 

 

 

 

 

 

 

Действие

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Данные

 

 

 

 

 

 

Операции ввода-вывода

 

 

 

 

Данные

 

 

 

 

 

 

 

 

 

Решение

 

 

 

 

 

 

Ветвления, выбор, циклы

 

 

 

 

Условие

 

 

 

 

 

 

 

 

 

Подготовка

 

 

 

 

 

 

Счётные циклы

 

 

 

 

Действия

 

 

 

 

 

 

 

 

 

Граница цикла

 

 

 

 

 

 

Любые циклы

 

 

 

 

Начало

 

 

 

 

 

Конец

 

 

 

 

 

 

 

 

 

Предопределённый

 

 

 

 

 

 

Вызов процедур

 

 

 

 

 

 

процесс

 

 

 

Имя

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Соединитель

 

 

 

Имя

Маркировка разрывов линий

 

 

 

 

 

 

 

 

 

 

 

Комментарий

 

 

 

Комментарий

Пояснения к операциям

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4

Учебное пособие по дисциплине “Программная инженерия”

После того, как в 60-х годах XX в. было доказано, что любой сколь угодно сложный алгоритм мож-

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

мирования высокого уровня появились управляющие операторы для реализации соответствующих конструкций (рис. 2.1).

нет

Действие1

Условие

Условие

да

Действие2

 

Действие1

 

 

Действие2

 

 

Действие

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

а)

б)

в)

 

Рисунок 2.1.— Базовые алгоритмические структуры (а — следование, б— ветвление, в — цикл - пока)

Следование — обозначает последовательное выполнение действий. Ветвление — соответствует выбору одного из двух вариантов действий. Цикл-пока определяет повторение действий, пока не будет нарушено некоторое условие, выполнение которого проверяется в начале цикла.

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Код

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Действие

 

 

 

i=n1,n2,h

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Действие1

 

Действие2

 

Действие3

 

 

 

 

 

 

 

 

 

 

 

 

 

нет

 

 

Действие

 

 

 

 

 

 

 

 

 

 

Условие

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

да

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

а)

 

 

 

 

 

 

 

 

 

 

в)

 

 

 

 

 

 

 

 

б)

 

 

Рисунок 2.2.—Дополнительные алгоритмические структуры (а — выбор, б— цикл-до, в — цикл с заданным числом повторений)

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

Рассматриваемые на данном лабораторном занятии шесть конструкций были положены в основу структурного программирования.

5

Учебное пособие по дисциплине “Программная инженерия”

На рисунке 2.3 предложен пример алгоритма поиска максимального элемента массива

i:=0;

нет

i<=n AND

 

A[i]<>y

 

 

 

 

 

 

да

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

нет

 

 

 

 

 

 

 

 

 

 

 

i:=i+1;

i<n

 

 

 

 

 

 

 

 

 

 

 

 

 

 

да

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

“Элемент

 

 

“Элемент не

 

найден”

 

 

найден”

Рисунок 2.3.—Реализация поискового цикла в массиве

Задание

Задание выполняется группой из 2-3 студентов на согласованным с преподавателем языке программирования высокого уровня. В соответствии с вариантами задания обучаемыми разрабаты-

вается блок-схема алгоритма и соответствующий ему исходный код.

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

Вариант 1. Алгоритм сортировки одномерного массива простым обменом.

Алгоритм основан на следующем принципе: осуществляется просмотр всех элементов массива с целью выявления элемента с наименьшим весом, найденный элемент переносится в первую позицию массива, а основные элементы смещаются. На следующей итерации алгоритма процедура повторяется, но уже без учёта первого элемента, и т.п. Очень часто этот метод называют “пузырьковым”, когда элемент с наименьшим весом всплывает на поверхность (рис. 2.4).

6

Учебное пособие по дисциплине “Программная инженерия”

44

06

06

06

06

06

06

06

55

44

12

12

12

12

12

12

12

55

44

18

18

18

18

18

42

12

55

55

42

42

42

42

94

42

42

42

55

44

44

44

18

94

94

94

94

94

55

55

06

18

18

44

44

55

94

67

67

67

67

67

67

67

67

94

Рисунок 2.4.—Сортировка простым обменом

Вариант 2. Алгоритм сортировки одномерного массива шейкер-сортировкой.

Сортировка пузырьковым методом обладает примечательным недостатком – один неправильно расположенный “лёгкий пузырёк” расположенный в “тяжёлом конце” всплывёт на место за один проход.

Например: 12,8,42,44,55,67,94,06

Неправильно расположенный элемент в “лёгком” конце массива будет опускаться за несколько проходов.

Например: 94,06,12,8,42,44,55,67

Эта неестественная асимметрия подсказывает направление улучшения алгоритма – менять направление следующих друг за другом проходов. Работа такого алгоритма продемонстрирована рисунком 2.5.

44

06

06

06

06

06

06

06

55

44

44

12

12

12

12

12

12

55

55

55

55

18

18

18

42

12

12

44

44

44

44

42

94

42

42

42

42

42

42

44

18

94

67

67

18

55

55

55

06

18

18

18

67

67

67

67

67

67

94

94

94

94

94

94

В отличие от сортировки пузырьком (которая не Рисунок 2.5.—Шейкер-сортировка находит места в серьёзных программах), шей-

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

Вариант 3. Алгоритм сортировки одномерного массива простым выбором.

Метод основан на следующем правиле:

находится элемент с наименьшим значением;

найденный элемент меняется местами с первым элементом a1.

Эти операции повторяются с n-1 элементами, затем с n-2, и т.д. пока не останется только один элемент – наибольший (рис. 2.6).

7

Учебное пособие по дисциплине “Программная инженерия”

44

55

12

42

94

18

06

67

06

55

12

42

94

18

44

67

06

12

55

42

94

18

44

67

06

12

18

42

94

55

44

67

06

12

18

42

94

55

44

67

06

12

18

42

44

55

94

67

06

12

18

42

44

55

94

67

06

12

18

42

44

55

67

94

Рисунок 2.6.—Сортировка простым выбором

Вариант 4. Алгоритм сортировки одномерного массива простыми вставками.

Элементы исходного массива условно раз-

 

 

 

 

 

 

 

 

деляются

на готовую последовательность

44

55

12

42

94

18

06

67

 

 

 

A[0], …, A[i] и входную последовательность

 

 

 

 

 

 

 

 

A[i+1], …, A[n]. На каждом шаге, начиная с

44

55

12

42

94

18

06

67

i=1 и увеличивая i на единицу берут i –й

 

 

 

 

 

 

 

 

элемент

входной

последовательности и

12

44

55

42

94

18

06

67

передают в готовую последовательность,

 

 

 

 

 

 

 

 

вставляя его на подходящее место. Поря-

12

42

44

55

94

18

06

67

док работы алгоритма отражён на рисунке

 

 

 

 

 

 

 

 

2.7.

 

 

12

42

44

55

94

18

06

67

Обратите внимание, что сортировки про-

12

18

42

44

55

94

06

67

 

 

 

стыми вставками и простым выбором яв-

 

 

 

 

 

 

 

 

ляются в

некоторой степени противопо-

06

12

18

42

44

55

94

67

 

 

 

ложностью друг другу. При простой вставке

 

 

 

 

 

 

 

 

на каждом шаге

рассматривается лишь

06

12

18

42

44

55

67

94

один очередной элемент исходной после-

 

 

 

 

 

 

 

 

довательности и все элементы готовой по-

Рисунок 2.7.—Сортировка простыми вставками

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

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

Вариант 5. Алгоритм сортировки одномерного массива бинарными вставками.

Алгоритм сортировки простыми вставками можно улучшить, пользуясь тем, что готовая последовательность A[0],…,A[i] (в которую нужно включить новый элемент) уже упорядочена. Поэтому место включения можно найти значительно быстрее.

Будем разбирать алгоритм, рассматривая его действия на i-м шаге. Как говорилось выше, последовательность к этому моменту разделена на две части: готовую A[0]...A[i] и неупорядоченную

8

Учебное пособие по дисциплине “Программная инженерия”

A[i+1]...A[n]. Выбираем любой элемент из неупорядоченной последовательности и сравниваем его с элементом, находящимся в центре уже отсортированной последовательности.

Часть A[0]..A[4] уже упорядочена.

Центр упорядоченной последовательности

12

42

44

55

94

18

06

67

44 > 18,

значит 18 будет находиться левее 44

Рисунок 2.8.—Шаг сортировки бинарными включениями

Произведя сравнение, мы получаем важную информацию о том, в какой половине уже отсортированной последовательности должен оказаться очередной элемент. В нашем случае (см. рис. 2.8) элемент 18 меньше 44, поэтому он должен попасть левее элемента массива со значением 44. Далее операция повторяется с выбранной частью отсортированной последовательности до тех пор, пока наш элемент не попадёт в установленное место.

Вариант 6. Имеется 2-мерный массив размерностью N x M. Разработать алгоритм подсчёта суммы элементов выше главной диагонали двухмерного массива.

Примечание: В листингах 2.1 и 2.2 представлен исходный код консольного приложения, демонстрирующий порядок заполнения случайными числами 1-мерного массива размерностью N элементов.

Листинг 2.1. Заполнение массива случайными числами на языке Delphi

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses System.SysUtils;

const N=10; //число элементов в массиве

var A:Array[0..N-1] of integer;//одномерный массив i:integer;

begin

// ======= ЗАПОЛНЕНИЕ МАССИВА СЛУЧАЙНЫМИ ЧИСЛАМИ ==========

Randomize; //инициализация генератора случайных чисел for i :=Low(A) to High(A) do //цикл заполнения

begin

A[i]:=Random(100); //передача случайного числа в элемент Write(A[i],#9); //вывод элемента массива на экран

end; //==========================================================

{ВАШ КОД ДОЛЖЕН НАХОДИТЬСЯ ЗДЕСЬ!!!}

ReadLn(i); end.

Листинг 2.2. Заполнение массива случайными числами на языке C++ Builder

#pragma hdrstop #pragma argsused

#include <tchar.h>

9

Учебное пособие по дисциплине “Программная инженерия”

#include <stdio.h> #include <stdlib.h> #include <iostream>

int _tmain(int argc, _TCHAR* argv[])

{

const N=10;

int a[N-1]; //массив из N элементов

// ======= ЗАПОЛНЕНИЕ МАССИВА СЛУЧАЙНЫМИ ЧИСЛАМИ ==========

randomize(); //инициализация генератора случайных чисел

for (int i = 0; i <= N-1; i++ )

{ a[i]=random(100); //присваиваем i-му элементу случайное значение std::cout<<a[i]<<"\t"; //вывод элемента массива на экран

}

//==========================================================

{ВАШ КОД ДОЛЖЕН НАХОДИТЬСЯ ЗДЕСЬ!!!}

std::cin>>a[0]; return 0;

}

10