Книга: Технологии программирования

5.11. ПРИМЕР ПРИМЕНЕНИЯ ПРОЕКТНОЙ ПРОЦЕДУРЫ ДЛЯ КОДИРОВАНИЯ ПРОГРАММЫ ПЕЧАТИ КАЛЕНДАРЯ НА ПРИНТЕРЕ

5.11. ПРИМЕР ПРИМЕНЕНИЯ ПРОЕКТНОЙ ПРОЦЕДУРЫ ДЛЯ КОДИРОВАНИЯ ПРОГРАММЫ ПЕЧАТИ КАЛЕНДАРЯ НА ПРИНТЕРЕ

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

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

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

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

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

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

Программа печати календаря заданного года
Укажите год распечатываемого календаря после 1917 года
(Не могу составить календарь  года
Для завершения программы нажмите любую клавишу…)
Ждите, идет печать…
Для завершения программы нажмите любую клавишу…


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

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

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

Program Calendar;
{Программа печати календаря заданного года на матричном принтере.
Год должен быть начиная с YEARBASE года}
Uses
Crt, Dos;
Const
YEARBASE = 1917; {Начальный базовый год }
BLANKS1917 = 0; {Число пустых клеток в начале января базового года}
KVARTALNAME: array [1…4] of String [53] =
({Константы укорочены при макетировании! }
' Январь Февраль Март',
' Апрель Май Июнь',
' Июль Август Сентябрь',
' Октябрь Ноябрь Декабрь'
WEEKDAYNAME: Array [1…7] of String [2] = ('Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс');
Var
F: Text; {Файловая переменная}
Year: Word; {Год распечатываемого календаря}
Kvartal: Word; {Квартал года}
{Количество дней в каждом месяце}
MonthsDays: Array [1…12] of Word;
{Количество пустых клеток в начале января года Year}
Balnks: Word;
{Количество пустых клеток в начале каждого месяца }
BlanksDaus: Array [1…12] of Word;
idW: Word; {Номер дня недели }
iMonth: Word; {Номер месяца в году }
iKvartalMonth: Word; {Номер месяца в квартале }
iCol: Word; {Номер колонки в месяце квартала }
iCell: Word; {Номер клетки в месяце квартала}
i: Integer;
Function Vys (Year: Word): Boolean;
{Функция возвращает True в случае високосности года Year}
begin
Vys: = False;
if (((Year mod 4 = 0) and (Year mod 100<>0))
or (Year mod 1000 = 0))
then
Vys: = True;
end; {Vys}
begin { Основная программа }
ClrScr; {Очистка экрана }
Write ('Программа печати календаря');
WriteLn ('заданного года');
Write ('Укажите год распечатываемого');
WriteLn ('календаря после', YEARBASE: 5, 'года');
ReadLn (Year);
{Контроль введенного года }
if Year < YEARBASE then
begin
{Аварийное завершение программы }
Write ('He могу составить календарь');
WriteLn (Year: 5, 'года');
Write ('Для завершения программы');
WriteLn ('нажмите любую клавишу…');
repeat until KeyPressed;
Halt (1);
end;
WriteLn ('Ждите, идет печать…');
Assign (F, 'PRN');
Rewrite (F);
{Печать календаря на принтере }
{Часть пробелов в следующей строке была изъята!}
WriteLn (F, ' ', Year);
{Подготовка информации}
{Определение количества пустых клеток в январе года Year}
Blanks: = BLANKS1917;
i:= YEARBASE;
while (I Year) do begin
{Увеличение Blanks}
Inc (Blanks); {В любой год плюс 1 }
if Vys (i)
then
Inc (Blanks); {Прошлый год високосный, +2}
{Корректировка Blanks}
if (Blanks >= 7) then Blanks:= Blanks — 7;
Inc (i); {Текущий год }
end;
{Определение количества дней в каждом месяце }
for i:= 1 to 12 do
MonthsDays [i]:= 31;
MonthsDays [4]:= 30;
MonthsDays [6]:= 30;
MonthsDays [9]:= 30;
MonthsDays [11]:= 30;
MonthsDays [2]:= 28;
if Vys (Year) then MonthsDays [2]: = 29;
{Определение количества пустых клеток в начале каждого месяца }
BlanksDays [1]:= Blanks;
for i: = 2 to 12 do
if BlanksDays [i — 1] + MonthsDays [i — 1] < 35
then
BlanksDays [i]:= BlanksDays [i — 1] + MonthsDays [i — 1] — 28
else
BlanksDays [i]:= BlanksDays [i — 1] + MonthsDays [i — 1] — 35;
{Задание номеров кварталов }
{Печать тела календаря }
for Kvartal:= 1 to 4 do begin
{Печать наименования квартала }
WriteLn (F, KVARTALNAME [Kvartal]);
{Печать дат квартала }
{Задание номера дня недели }
for iDW:= 1 to 7 do
begin
{Печать наименования дней недель }
Write (f, WEEKDAYNAME [iDW];
{Печать трех месяцев дат квартала }
for iKvartalMonth: = 1 to 3 do begin
{Расчет номер месяца в квартале }
iMonth: = (Kvartal — 1) * 3 + iKvartalMonth;
{Печать шести колонок дат дня недели квартала}
for iCol:= 1 to 6 do begin
iCell:= (iCol — 1)*7 + iDW;
if ((iCell > BlanksDays [iMonth]) and (iCell <= BlanksDays [iMonth] + MonthsDays [iMonth]))
then
Write (F, iCell — BlanksDays [iMonth]: 3)
else
Write (F, ' ');
end;
end;
{Печать наменования дней недель }
WriteLn (F, WEEKDAYNAME [iDW];
end;
end;
Close (F);
Write ('Для завершения программы');
WriteLn ('нажмите любую клавишу…');
Repeat until KeyPressed;
end.

ВЫВОДЫ

• С появлением ЭВМ актуальным стал поиск способов описания вычислительных алгоритмов. В 60-х годах уже применялись два способа описания алгоритмов: словесный пошаговый и графический в виде схем алгоритмов (жаргонно: блок-схем алгоритмов).

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

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

• Любые алгоритмы или эвроритмы должны состоять только из стандартных структур. Каждая стандартная структура строго имеет один информационный вход и один информационный выход. Использование иных (нестандартных) структур приводит либо к удлинению описания, либо к невозможности тестирования (из-за нереально огромного объема необходимых тестов), либо к потере понятности.

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

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

• Первоначально алгоритм или эвроритм должен представлять одну типовую структуру СЛЕДОВАНИЕ (одно действие со смыслом "выполнить все действия программы"). Далее до достижения элементарных действий (элементарных операторов языка программирования или элементарных операций) отдельные структуры СЛЕДОВАНИЕ декомпозируются с соблюдением принципа от общего к частному одной из трех стандартных структур: ЦЕПОЧКА СЛЕДОВАНИЙ; ЦЕПОЧКА АЛЬТЕРНАТИВ; ПОВТОРЕНИЕ.

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

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

• Тесты — необходимый атрибут разработки алгоритма.

• Обобщающий тест или тесты — минимальный набор тестовых данных, охватывающих все возможные случаи вычислений.

• Алгоритмы из старых книг лучше понимаются после их рефакторинга.

КОНТРОЛЬНЫЕ ВОПРОСЫ

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

2. Что такое функциональное описание?

3. Для чего предназначена проектная процедура разработки функциональных описаний?

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

5. В каких случаях программисты могут применять проектную процедуру?

6. В каких случаях не программисты могут применять проектную процедуру?

7. Каковы основные характеристики структур СЛЕДОВАНИЕ, АЛЬТЕРНАТИВА и ПОВТОРЕНИЕ?

8. Каков порядок основных шагов (этапов) выполнения проектной процедуры?

9. Приведите пример описания внешних и внутренних данных программы.

10. Зачем нужна модель "черного ящика"?

11. Назовите тесты, разрабатываемые до программирования. Назначение. Содержание. Формы.

12. Назовите признаки структуры ЦЕПОЧКА СЛЕДОВАНИЙ.

13. Назовите порядок детализации одиночного СЛЕДОВАНИЯ.

14. Назовите порядок детализации ЦЕПОЧКИ СЛЕДОВАНИЙ.

15. Назовите признаки структур вида АЛЬТЕРНАТИВА.

16. Назовите порядок детализации ЦЕПОЧКИ АЛЬТЕРНАТИВ.

17. Запишите пример кодировки альтернатив с одним и двумя действиями.

18. Запишите пример кодировки альтернатив с тремя и более действиями.

19. Назовите признаки структуры ПОВТОРЕНИЕ.

20. Назовите порядок детализации структур универсальных циклов ДО и ПОКА.

21. Запишите пример кодировки структуры НЕУНИВЕРСАЛЬНЫЙ ЦИКЛ-ДО.

22. Запишите пример кодировки структур УНИВЕРСАЛЬНЫЕ ЦИКЛЫ ДО и ПОКА.

23. Как производится доказательство корректности алгоритмов при выполнении проектной процедуры.

24. Дополните описание процесса "Кипячение воды в чайнике" наглядными рисунками.

Оглавление книги


Генерация: 2.450. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз