Ниже дано решение двух схожих за смыслом задач на использование оператора выбора Case. Первая задача – нахождение даты, предшествовавшей указанной (для невисокосного года). Вторая – нахождение даты, которая следует за указанной. Условие невисокосного года указывать нужно, поскольку в противном случае код несколько усложняется.
Идея решения заключается в следующем. Во-первых, надо сгруппировать разные месяцы так, чтобы вместе оказались месяцы с равным количеством дней и это упростит проверку, во-вторых, проверять отдельно: 1) только 1-е число и остальную часть месяца (в случае предшествующей даты); 2) только последнее число и остальную часть (в случае следующей даты). Поскольку перед 1-м числом стоит последнее число предыдущего месяца, а за последним числом идет 1-е число следующего месяца, то эти случаи надо рассматривать отдельно.
Далее пример кода для решения задачи Case8 из электронного задачника Абрамяна. В условии задания предполагается, что вводится именно правильная дата, то есть существующая. Если дата введена неверно, то результат, естественно, тоже будет неверным. Все остальные пояснения в комментариях программы.
Сase8. Даны два целых числа: D (день) и M (месяц), определяющие правильную дату невисокосного года. Вывести значения D и M для даты, предшествующей указанной.
var
D, M: byte;
begin
{ ВВОДИМ ДЕНЬ И МЕСЯЦ: }
write('D = ');
readln(D); { <-- Вводим значение дня }
write('M = ');
readln(M); { <-- Вводим значение месяца }
writeln;
{ Проверяем 1-й день: }
if D = 1 then begin
{ Находим последний день предшествующего месяца: }
case M of
{ Для 1-го дня 3-го месяца предшествующим
является 28-й день: }
3: D := 28;
{ Для 1-го дня 5-го, 7-го, 10-го и 12-го месяцев
предшествующим является 30-й день: }
5,7,10,12: D := 30;
{ Для 1-го дня 1-го, 2-го, 4-го, 6-го, 8-го, 9-го и
11-го месяцев предшествующим является 31-й день: }
1,2,4,6,8,9,11: D := 31
end;
{ Номер предшествующего месяца. Для M = 1 он равен 12,
а для остальных M - 1. Можем использовать такую формулу: }
M := (M + 10) mod 12 + 1
end { Остальные дни уменьшаем на 1 (месяц не изменяется): }
else dec(D);
{ ВЫВОДИМ РЕЗУЛЬТАТ с форматированием. Если число
имеет одну цифру, то в начале добавляем 0: }
write('Предшествующая дата: ');
if D < 10 then write('0', D, '.')
else write(D, '.');
if M < 10 then writeln('0', M)
else writeln(M);
readln
end.
**type** byte;
: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255A **mod** B
- остаток при целочисленном делении А на В**procedure** Dec(**var** i: integer);
: Уменьшает значение переменной i на 1 * * *
Ниже представлено второе решение задачи Case8. Этот код включает в себя проверку правильности введенных данных, а также сообщение, если указанная дата не существует. Сначала вводим и проверяем данные (строки 10 – 29), а потом повторяем код первого варианта решения задачи (строки 32 – 59). В комментариях все пояснения.
var
D, M, N: byte;
f: boolean; { True - дата существует, False - не существует }
begin
{ ВВОДИМ ДЕНЬ И МЕСЯЦ. Для этого используем цикл: сначала
вводим значение дня и месяца, потом проверяем, существует
ли указанная дата; если дата не существует, то ввод
повторяется. Если дата существует, то выходим из цикла: }
repeat
write('D = ');
readln(D); { <-- Вводим день }
write('M = ');
readln(M); { <-- Вводим месяц }
{ Проверяем, является ли введенная дата правильной: }
f := true; { <-- Считаем, что введенная дата правильная }
case M of
{ Второй месяц имеет 28 дней: }
2: if (D < 1) or (D > 28) then f := false;
4,6,9,11: { <-- Месяцы имеют 30 дней }
if (D < 1) or (D > 30) then f := false;
1,3,5,7,8,10,12: { <-- Месяцы имеют 31 день }
if (D < 1) or (D > 31) then f := false
else f := false { <-- M<1 или M>12 }
end;
if f = false then writeln(' Такой даты не существует!')
until f; { <-- Выходим, если введенная дата правильная }
writeln;
{ НАХОДИМ ПРЕДШЕСТВУЮЩУЮ ДАТУ }
if D = 1 then begin { <-- Проверяем 1-й день: }
{ Находим последний день предшествующего месяца: }
case M of
{ Для 1-го дня 3-го месяца предшествующим
является 28-й день: }
3: D := 28;
{ Для 1-го дня 5-го, 7-го, 10-го и 12-го месяцев
предшествующим является 30-й день: }
5,7,10,12: D := 30;
{ Для 1-го дня 1-го, 2-го, 4-го, 6-го, 8-го, 9-го и
11-го месяцев предшествующим является 31-й день: }
1,2,4,6,8,9,11: D := 31
end;
{ Номер предшествующего месяца. Для M = 1 он
равен 12, а для остальных M - 1: }
if M = 1 then M := 12
else M := M - 1
end { Остальные дни уменьшаем на 1 (месяц не изменяется): }
else dec(D);
{ ВЫВОДИМ РЕЗУЛЬТАТ. Если число имеет одну цифру,
то в начале добавляем 0: }
write('Предшествующая дата: ');
if D < 10 then write('0', D, '.')
else write(D, '.');
if M < 10 then writeln('0', M)
else writeln(M);
readln
end.
**type** byte;
: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255**type** boolean;
: Представляет логическое значение.**const** true = True;
: Представляет логическое значение.**const** false = False;
: Представляет логическое значение.**const** false = False;
: Представляет логическое значение.**const** false = False;
: Представляет логическое значение.**const** false = False;
: Представляет логическое значение.**const** false = False;
: Представляет логическое значение.**procedure** Dec(**var** i: integer);
: Уменьшает значение переменной i на 1 Сase9. Даны два целых числа: D (день) и M (месяц), определяющие правильную дату невисокосного года. Вывести значения D и M для даты, следующей за указанной.
Эта задача отличается от предыдущей тем, что здесь надо искать следующую за указанной дату. Смысл решения в том, чтобы для каждого месяца посчитать количество в нем дней. Потом, если введенный день лежит в интервале от 1-го до предпоследнего, то увеличиваем его на 1. Если же мы ввели последний день месяца, то за ним наступает первое число, а месяц увеличивается на 1. Как и в первом решении зазания Case8, предполагается, что мы ввели правильную (существующую) дату для невисокосного года.
var
D, M, CountDay: byte;
begin
{ ВВОДИМ ДЕНЬ И МЕСЯЦ: }
write('D = ');
readln(D); { <-- Вводим значение дня }
write('M = ');
readln(M); { <-- Вводим значение месяца }
writeln;
{ ПРОВЕРЯЕМ МЕСЯЦЫ ГОДА: }
{ Группируем месяцы по количеству дней: }
case M of
{ Второй месяц имеет всего 28 дней: }
2: CountDay := 28;
{ Следующие месяцы имеют по 30 дней: }
4, 6, 9, 11:
CountDay := 30;
{ Следующие месяцы имеют по 31 день: }
1, 3, 5, 7, 8, 10, 12:
CountDay := 31
end;
{ Если D < CountDay, то увеличиваем день D на единицу;
если D = CountDay, то следующий день равен 1, а месяц
увеличивается на 1 (первый день следующего месяца): }
if D < CountDay then inc(D)
else begin
M := M mod 12 + 1;
D := 1
end;
{ ВЫВОДИМ РЕЗУЛЬТАТ: }
write('Следующая дата: ');
if D < 10 then write('0', D, '.')
else writeln(D, '.');
if M < 10 then write('0', M)
else writeln(M);
readln
end.
**type** byte;
: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255**procedure** Inc(**var** i: integer);
: Увеличивает значение переменной i на 1A **mod** B
- остаток при целочисленном делении А на В * * *
Второе решение задачи Case9 предполагает проверку правильности введенных данных. Сначала вводим и проверяем данные (строки 8 – 27), находим количество дней CountDay для каждого месяца (строки 35 – 46), а потом определяем D и M в зависимости от CountDay (строки 50 – 54) и выводим результат (строки 56 – 60). В комментариях все пояснения.
var
D, M, CountDay: byte;
f: boolean;
begin
{ ВВОДИМ ДЕНЬ И МЕСЯЦ до тех пор, пока не
будет введена правильная дата: }
repeat
write('D = ');
readln(D); { <-- Вводим день }
write('M = ');
readln(M); { <-- Вводим месяц }
{ Проверяем, является ли введенная дата правильной: }
f := true; { <-- Считаем, что введенная дата правильная }
case M of
{ Второй месяц имеет 28 дней: }
2: if (D < 1) or (D > 28) then f := false;
4,6,9,11: { <-- Месяцы имеют 30 дней }
if (D < 1) or (D > 30) then f := false;
1,3,5,7,8,10,12: { <-- Месяцы имеют 31 день }
if (D < 1) or (D > 31) then f := false
else f := false { <-- M<1 или M>12 }
end;
if f = false then writeln(' Такой даты не существует!')
until f; { <-- Выходим, если введенная дата правильная }
writeln;
write('Вы ввели дату: ');
if D < 10 then write('0', D, '.')
else write(D, '.');
if M < 10 then writeln('0', M)
else writeln(M);
{ Группируем месяцы по количеству дней: }
case M of
{ Второй месяц имеет всего 28 дней: }
2: CountDay := 28;
{ Следующие месяцы имеют по 30 дней: }
4, 6, 9, 11:
CountDay := 30;
{ Следующие месяцы имеют по 31 день: }
1, 3, 5, 7, 8, 10, 12:
CountDay := 31
end;
{ Если D < CountDay, то увеличиваем день D на единицу;
если D = CountDay, то следующий день равен 1, а месяц
увеличивается на 1 (первый день следующего месяца): }
if D < CountDay then inc(D)
else begin
M := M mod 12 + 1;
D := 1
end;
{ ВЫВОДИМ РЕЗУЛЬТАТ: }
write('Следующая дата: ');
if D < 10 then write('0', D, '.')
else writeln(D, '.');
if M < 10 then write('0', M)
else writeln(M);
readln
end.
**type** byte;
: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255**type** boolean;
: Представляет логическое значение.**const** true = True;
: Представляет логическое значение.**const** false = False;
: Представляет логическое значение.**const** false = False;
: Представляет логическое значение.**const** false = False;
: Представляет логическое значение.**const** false = False;
: Представляет логическое значение.**const** false = False;
: Представляет логическое значение.**procedure** Inc(**var** i: integer);
: Увеличивает значение переменной i на 1A **mod** B
- остаток при целочисленном делении А на В