Программа выдает неверный вывод для високосного года, значение переменной нагрузки неверно, я думаю, например, 1900,1700

#c #if-statement #conditional-operator #leap-year

Вопрос:

*Программа выдает неверные выходные данные за столетний год, которые не являются високосными, например, 1900,1700.Программа выдает неверный вывод для високосного года, значение переменной нагрузки неверно, я думаю, например, 1900,1700. *

 #include <iostream>

using namespace std;

int main()
{
    int year;
    bool t1=true;
    cout<<t1;
    bool t2=false;
    cin>>year;
    if(year%4==0)
    {
       int value=year0?year@0?t1:t2:t1;
       cout<<value;
       if(value==t1)
       {
           cout<<"leap year";
       }
       else
       {
           cout<<"not a leap year";
       }
    }
    else
    {
        cout<<"not a leap year";
    }
}
 

Комментарии:

1. int value=year0?year@0?t1:t2:t1; только почему?

2. Как ты думаешь year0? , что делает? Или что оператор % вообще делает для ints?

3. Пусть все будет просто…. Не делай таких вещей, как year0?year@0?t1:t2:t1;

4. Почему у вас есть такие переменные, как t1 и t2

5. Даже не обращая внимания на нечитабельность int value= ... вопроса, почему вы решили написать «t1» и «t2» вместо «истина» и «ложь»? (Если вы упростите это, вы найдете year % 100 == 0 || year % 400 != 0 .)

Ответ №1:

year0 становится ложным, когда year делится на 100 (остаток равен нулю), и становится истинным, когда year не делится на 100 (остаток не равен нулю).

year@0 становится ложным, когда year делится на 400 (остаток равен нулю), и становится истинным, когда year не делится на 400 (остаток не равен нулю).

Следовательно, вы должны оценивать число как не високосный год, когда year0 оно ложно и year@0 истинно, и как не високосный год в противном случае.

В заключение, строка

 int value=year0?year@0?t1:t2:t1;
 

должно быть

 bool value=year0?t1:year@0?t2:t1;
 

Кроме того, я не думаю, что использование int здесь для назначения bool переменных разумно.

Комментарии:

1. Конечно, это исправление, но это все еще нечитаемый трудный для поддержания беспорядок…

2. @JHBonarius: На мой взгляд, это читается на C , хотя t1 и t2 нуждается в доработке. Но имейте в виду, что PHP изменил ассоциативность. Забавные ребята.

3. @Bathsheba нет, когда будущий разработчик посмотрит на этот код, ему/ей/им придется приложить некоторые усилия, чтобы понять его. Я бы сделал функцию bool IsDivisibleBy(int num, int divisor) { return num % divisor == 0; } и одну bool IsLeapYear(int year) { return (IsDivisibleBy(year, 4) amp;amp; !IsDivisibleBy(year, 100)) || IsDivisibleBy(year, 400);} . Это то, что я считаю читабельным. (Я опускаю [[nodiscard]] , static , constexpr , и noexcept )

Ответ №2:

В дополнение к исправлению в ответе MikeCAT вы также можете значительно упростить свой код всего до нескольких строк:

 #include <iostream>

int main()
{
    int year;
    std::cin>>year;
    bool leap = (year % 4 == 0) amp;amp; ( (year % 100 != 0) || (year % 400 == 0) );
    if(leap)
    {
        std::cout<<"leap year";
    }
    else
    {
        std::cout<<"not a leap year";
    }
}
 

Вы можете использовать 0 эквивалент false , чтобы сделать его короче, но я думаю, что первая версия более читабельна:

     bool leap = !(year % 4) amp;amp; ( (year % 100) || !(year@0) );
 

Комментарии:

1. @4386427 мне это не кажется намного проще, и у меня есть теоретическое небольшое преимущество в производительности от остановки оценки короткого замыкания после первого срока для 3/4 входных значений, это также в логическом порядке, в котором большинство людей подумали бы о правилах високосного года

2. Отчасти это правда… логика кажется мне более простой, но.. вы правы насчет короткого замыкания

Ответ №3:

Как только компиляторы правильно реализуют C 20 (который еще не выпущен), вам не нужно изобретать велосипед и вы можете использовать std::chrono::year::is_leap

 #include <iostream>
#include <chrono>

int main() {
    using namespace std::chrono;

    year y = 1900y;
    std::cout << "year: " << static_cast<int>(y)
              << " is " << (y.is_leap()?"":"not ") << "a leap yearn";
}
 

божья молния