Это хорошая идея, чтобы упростить ваши условия. Общий метод для этого состоит в том, чтобы преобразовать в нормальную форму — конъюнктивную или дизъюнктивную — и поставить сначала те тесты, которые с наибольшей вероятностью вызовут короткое замыкание. Для таких простых случаев, как этот, вы можете просто посмотреть на это.
В этом случае конъюнктивная нормальная форма чрезвычайно проста:
year%4 == 0 &&
( year < 1582 || year%100 != 0 || year%400 == 0 )
То есть год делится на четыре и ни одно из трех условий реформы григорианского календаря не выполняется. Так как первый &&
терм, который является ложным, и первый ||
термин, который является истинным, сокращают выражение, мы хотим поместить предложения, которые, скорее всего, будут сокращаться первыми.
Обратите внимание, что вы можете кодировать от year%100 != 0
до year%100
внутри условного выражения, а от year%2000 == 0
до !(year%2000)
, если вам так легче читать.
Имеет смысл перенести это во вспомогательную функцию. Мы можем пометить его constexpr
, чтобы дать компилятору подсказку, что он может вычислить, являются ли константы високосными годами или нет, во время компиляции.
Я не люблю публиковать полные ответы на домашние задания, но этот корабль уплыл.
#include <cstdlib>
#include <iostream>
using std::cin;
using std::cout;
constexpr bool is_leap(const int year)
{
// Conjunctive normal form:
return ( year%4 == 0 &&
( year < 1582 || year%100 != 0 || year%400 == 0 ) );
}
int main()
{
int year = 0; // Used only within the body of the loop that sets it.
while (cin >> year)
cout << year
<< ( is_leap(year) ? " is a leap year.\n"
: " is not a leap year.\n" );
return EXIT_SUCCESS;
}
Даже для такой тривиальной программы, как эта, стоит подумать над проектным решением: объявить ли мы int year;
неинициализированным или инициализировать его неверным значением, таким как int year = 0;
? В данном случае это безопасно в любом случае, потому что year
используется только внутри тела цикла, который его устанавливает. Однако, если мы не инициализируем его, мы можем позже реорганизовать код для использования year
вне цикла, и тогда может быть путь кода, где year
используется до его инициализации (вызывая неопределенное поведение!). С другой стороны, если мы инициализируем year
, мы можем помешать компилятору заметить, что есть путь, по которому он использовался до того, как он был инициализирован по-настоящему. Я лично предпочитаю инициализировать недопустимое значение и assert
, чтобы оно было обновлено перед использованием.
person
Davislor
schedule
22.10.2018
else
? - person Biffen   schedule 11.03.2016