Программа високосного года не работает

Вопрос - Год, в котором 366 дней, называется високосным. Год является високосным, если он делится на четыре (например, 1980), за исключением того, что он не является високосным, если он делится на 100 (например, 1900); однако это високосный год, если он делится на 400 (например, 2000). До введения григорианского календаря 15 октября 1582 года исключений не было. Напишите программу, которая запрашивает у пользователя год и вычисляет, является ли этот год високосным.

Это то, что у меня есть до сих пор, и программа, похоже, не работает больше 1582 лет. Может ли кто-нибудь помочь мне, почему? Большое спасибо

using namespace std;

int main()
{
cout<< "Pleas enter a year: " <<endl;
int year = 0;
cin >> year;

if (year <= 1581)
{
    if (year % 4 == 0)
    {
        cout << "It's a leap year, wow! " << endl;
    }

    else 
    {
        cout << "It's not a leap year " << endl;

    }
}

else if (year > 1581)
{
    if (year % 4 == 0)
    {
        if (year % 100 == 0)
        {
            cout<< "It is not a leap year " << endl;
        }
        else if (year % 400 == 0)
        {
            cout<< "It is a leap year, Wow!" << endl;
        }
    }

}

else
{
    cout<< "You entered a wrong year number "<< year<<  endl;
}

return 0;
}

person Sehajpreet Singh    schedule 11.03.2016    source источник
comment
С++? Отметьте как таковой, если он есть.   -  person Tiny    schedule 11.03.2016
comment
Что мне нужно ввести, чтобы добраться до последнего else?   -  person Biffen    schedule 11.03.2016


Ответы (7)


Вы все очень усложняете. Я не думаю, что вам нужно заботиться о том, больше ли год 1582 или нет (для 4-значного числа), при условии, что високосный год - это год, который:

• Делится на 400
ИЛИ
• НЕ делится на 100 И делится на 4.
Использование ненужных вложенных операторов if может сделать ваш код длинным и подверженным ошибкам . Попробуйте этот метод:

#include<iostream.h>
int main(){
    int y=0;
    cout << "Enter a year\n";
    cin >> y;
    cout <<"\n"<<y;
    if(y%400==0 || (y%100!=0 && y%4==0))
    cout <<" is a leap year";
    else
    cout <<" is not a leap year";
    return 0;
}
person Community    schedule 11.03.2016

Без проверки, если год > 1582

#include<iostream>
using namespace std;

int main()
{
    int year;
    cout<< "Please enter a year: " <<endl;
    cin >> year;

    if( year%25 && !(year&3) || !(year&15) )
        cout << "It's a leap year!" << endl;
    else
        cout << "It's not a leap year!" << endl;

    return 0;
}
person Community    schedule 26.05.2016

Вы упускаете ряд случаев в обработке лет после 1581 года.

  • печать «Не високосный год», если только (год % 4 == 0)
  • Третий случай, когда год, который делится на 4, не делится ни на 100, ни на 400.

Это так же просто, как вы просто не написали код, который запускается, например, в 2004 году.

person pmakholm    schedule 11.03.2016

Вам не хватает 2 утверждений else

using namespace std;

int main()
{
cout<< "Pleas enter a year: " <<endl;
int year = 0;
cin >> year;

if (year <= 1581)
{
    if (year % 4 == 0)
    {
        cout << "It's a leap year, wow! " << endl;
    }

    else 
    {
        cout << "It's not a leap year " << endl;

    }
}

else if (year > 1581)
{
    if (year % 4 == 0)
    {
        if (year % 100 == 0)
        {
            cout<< "It is not a leap year " << endl;
        }
        else if (year % 400 == 0)
        {
            cout<< "It is a leap year, Wow!" << endl;
        }
        // <----------- Here you are missing an else
    }
    // <----------- Here you are missing an else
}

else
{
    cout<< "You entered a wrong year number "<< year<<  endl;
}

return 0;
}
person Viktor Mellgren    schedule 11.03.2016
comment
@Walter Спасибо за конструктивный отзыв, в котором вы четко указали, какую ошибку я пропустил. - person Viktor Mellgren; 23.10.2018
comment
подумайте о том, что происходит для года = 2000. - person Walter; 23.10.2018

Я предлагаю

if (    ((year % 400) == 0)
     || (   ((year % 4) == 0) // or (year & 0x3) == 0
         && (   (year <= 1581)
             || ((year % 100) != 0) )))
   cout << "It's a leap year, wow! " << endl;
else
   cout << "It's not a leap year " << endl;

or

if (    ((year % 4) == 0) // or  year & 0x3 == 0
     && (   (year <= 1581)
         || ((year % 100) != 0)
         || ((year % 400) == 0) ) )
   cout << "It's a leap year, wow! " << endl;
else
   cout << "It's not a leap year " << endl;
person max66    schedule 11.03.2016

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

В этом случае конъюнктивная нормальная форма чрезвычайно проста:

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

Или вы можете просто написать следующую программу:

#include<iostream>
using namespace std;

int main()
{
    int year;
    cout << "Enter year: ";
    cin >> year;

    if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0){
        cout << "It is a leap year" << endl;
    }
    else{
        cout << "It is not a leap year" << endl;
    }
    return 0;
}
person Abdisamad Khalif    schedule 22.10.2018