Биоритмы
Упростить алгоритм можно за счет создания и использования массива из 12 целых чисел, содержащего количества дней по месяцам невисокосного года, т.е. 31, 28, 31, 30 и т.д. Этот массив (назовем его SIZE_OF_MONTH – длина _месяца) можно использовать и для обратной задачи, т.е. для определения даты критических дней, а также для проверки правильности вводимых дат. Таким образом, массив SIZE__OF_MONTH будет использоваться сразу в трех процедурах. Сделаем его глобальным, для чего его описание поместим перед описанием процедур:
const Size_of_Month: array – [1..12] of Byte = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); {--------------------------} Procedure InputDates (var d0,m0,y0,d,m,y: Integer); ………
Поскольку описание массива размещается до описания процедур, он становится доступным внутри каждой из процедур и служит для них глобальным. В отличие от этого все константы и переменные, объявляемые внутри некоторой процедуры, являются локальными и могут использоваться только в этой процедуре.
С учетом сказанного напишем следующий начальный вариант программной реализации процедуры INPUTDATES:
Procedure InputDates(var d0,m0,y0,d,m,y: Integer); {Вводит дату рождения и текущую дату. Контролирует правильность дат и их непротиворечивость (текущая дата должна быть позже даты рождения)} var correctly: Boolean; {Признак правильного ввода} begin {InputDates} repeat {Вводим и контролируем дату рождения d0,m0,y0.} {Вводим и контролируем текущую дату d,m,y.} {Проверяем непротиворечивость дат:} correctly: = у > у0; if not correctly and (у = y0) then begin correctly: = m > m0; if not correctly and (m = m0) then correctly: = d>=d0 end until correctly end; {InputDates}
В этой процедуре дважды выполняется одно и то же алгоритмическое действие (ввод и контроль даты). Это действие можно вынести в отдельную внутреннюю процедуру с именем INPDATE, тогда получим следующий окончательный вариант:
Procedure InputDates(var d0,m0,y0,d,m,y: Integer); {Вводит дату рождения и текущую дату. Контролирует правильность дат и их непротиворечивость (текущая дата должна быть позже даты рождения)} var correctly: Boolean; {Признак правильного ввода} {--------------------------} Procedure InpDate (text: String; var d,m,y: Integer); {Выводит приглашение TEXT, вводит дату в формате ДД ММ ГГГГ и проверяет ее правильность} const YMIN = 1800; {Минимальный правильный год} YМАХ = 2000; {Максимальный правильный год} begin {InpDate} repeat Write (text); ReadLn (d,m,y); correctly: = (y >= YMIN) and (Y <= YMAX) and (m >= 1) and (m <= 12) and (d > 0); if correctly then if (m = 2) and (d = 29) and (y mod 4=0) then {Ничего не делать: это 29 февраля високосного года!} else correctly: = d <= Size_of_Month[m]; if not correctly then WriteLn (' Ошибка в дате!') until correctly end; {InpDate} {--------------------------} begin {InputDates} repeat InpDate ('.Введите дату рождения в формате ДД ММ ГГГГ:',d0,m0,y0); InpDate (' Введите текущую дату: ',d,m,y); {Проверяем непротиворечивость дат:} correctly: = у > у0; if not correctly and (y = y0) then begin correctly: = m > m0; if not correctly and (m = m0) then correctly: = d >= d0 end until correctly end; {InputDates}