【问题标题】:Leap Year Basic C++ Boolean Always returns true闰年基本 C++ Boolean 总是返回 true
【发布时间】:2015-11-02 02:30:30
【问题描述】:

我编写了这段代码来确定输入的年份是否是闰年。意思是,那些能被 4 和 400 整除的是闰年,而不能被 100 或其他东西整除。

但是,我的程序总是为布尔值返回 true,因此输出会认为每年都是闰年。

到目前为止,这是我的代码:

#include <iostream>
#include <cmath>
#include <string>
#include <iomanip>

using namespace std;
 bool leap_year(int year);
int main()
{
    int year; 
     bool leap_year(int year);
    cout << "Please input the year in question: ";
    cin >> year;
    if (leap_year == false)
    {
        cout << "The year is not a leap year.  ";
    }
    else
    {
        cout << "The year is a leap year. ";
    }
    return 0;
}
  bool leap_year(int year)
{

    if (year % 4 == 0)
    {
        bool leap_year = true;
    }
    else if (year % 400 == 0)
    {
        bool leap_year = true;
    }
    else if (year % 100 == 0)
    {
        bool leap_year = false;
    }
    else
    {
        bool leap_year = false;
    }

    if (bool leap_year = false)
    {
        return false;
    }
    else
    {
        return true;
    }
}

【问题讨论】:

  • 它不应该总是返回true,因为it shouldn't compile
  • 它绝对可以编译。我正在使用 Visual Studio 2015 Express 版本作为编译器。
  • 有趣的是,GCC 也会编译它(带有警告)。但是,从一些阅读来看,我仍然相信 Clang 是对的。编辑:GCC 是错误的,我认为这是因为它仍然接受 false 作为空指针常量(即,它允许您执行 int* p = false;)。

标签: c++ boolean


【解决方案1】:

你声明了一堆局部变量

else if (year % 100 == 0)
{
    bool leap_year = false;
}

只要有 } 括号,此变量就会超出范围,您存储的值也会超出范围。

if (bool leap_year = false)
{
    return false;
}

这是定义一个变量leap_year 并将其赋值为false。 if 反过来将评估为 false,因此它总是会转到 else 条件。

我冒昧地重写了程序的一部分。您现在可以看到如何调用该函数。同样在函数中,一个局部变量 is_leap_year 用于存储返回值,最后被返回。我还更正了逻辑,因为之前第一个 %4 检查为真,并且不会执行其他 if 语句,这不是您想要的。

#include <iostream>
#include <cmath>
#include <string>
#include <iomanip>

using namespace std;
bool leap_year(int year);
int main()
{
    int year; 
    cout << "Please input the year in question: ";
    cin >> year;
    if (leap_year(year) == false)  //Call the function and check if return is false
    {
        cout << "The year is not a leap year.  ";
    }
    else
    {
        cout << "The year is a leap year. ";
    }
    return 0;
}
  bool leap_year(int year)
{
    bool is_leap_year = false;
    if (year % 4 == 0)
    {
       is_leap_year = true;
    }
    if (year % 100 == 0)
    {
        is_leap_year = false;
    }
    if (year % 400 == 0)
    {
        is_leap_year = true;
    }
    return is_leap_year;
}

【讨论】:

  • 感谢您的解释!!虽然尝试让 Leap_year 以其他方式返回主函数的值很有趣。
  • @marihikari 我已经用更改更新了您的原始程序。希望这可以解决问题。
  • 谢谢,这有点帮助,但我对它如何插入leap_year 函数感到困惑?
  • if (leap_year(year) == false) 是调用leap_year函数的地方。
  • 好的。明白了。再次感谢您的帮助,我对 C++ XD 还是很陌生;。
【解决方案2】:

应该是 IF ((year%4==0 && year%100 !=0) || (year%400 == 0) ) 返回 ISLEAPYEAR。

【讨论】:

    【解决方案3】:
    //You can simplify it like this:
    bool leap_year(int year)
    {
        bool leap_year  = false;
        if ((year % 4 == 0 && year%100 !=0) || year % 400 == 0)
        {
            bool leap_year = true;
        }
        return leap_year; 
    }
    

    为了避免这种情况:

    if (leap_year = false)
        {
            return false;
        }
    

    你可以像这样检查布尔值

    if (leap_year)
     {
            // code to execute when leap_year is true
     }
    

    【讨论】:

      【解决方案4】:

      你的问题是你返回true还是false的条件是:

      if (bool leap_year = false)
      {
          return false;
      }
      else
      {
          return true;
      }
      

      您正在将值 false 分配给您在条件语句中初始化的变量 leap_year。赋值运算符定义为:T&amp; T::operator =(const T2&amp; b),这意味着您总是在您的条件下评估false

      解决这个问题的一种方法是在bool leap_year(int year) 的顶部声明leap_year,而不是每次使用它(这是毫无意义的行为)。所以你的函数应该如下所示:

      bool leap_year(int year) {
          bool leap_year = false;
      
          if (year % 4 == 0) {
              leap_year = true;
          } else if (year % 400 == 0) {
              leap_year = true;
          } else if (year % 100 == 0) {
              leap_year = false;
          }
      
          if (leap_year == false) {
              return false;
          } else {
              return true;
          }
      }
      

      但更好的解决方案是使用the functionality that C++ already provides:

      bool leap_year(int year) {
          tm bar = { 0, 0, 0, 29, 1, year - 1900 };
      
          return static_cast<time_t>(-1) != mktime(&bar) && bar.tm_mday == 29 && bar.tm_mon == 1 && bar.tm_year == year - 1900;
      }
      

      [Live Example]

      【讨论】:

      • 那将是一个很好的解决方案。不知何故,当我尝试类似的东西时,它仍然不会返回错误值。将继续工作,但感谢您的回复:)
      • @marihikari +1 看来你是对的。 gcc 5.1.0 和 Visual Studio 2015 中似乎存在一个错误。我就那里发生的事情提出了一个新问题:stackoverflow.com/questions/33477379/…
      • @marihikari Success this answer 包含一个完全跨平台的标准实施解决方案!我已更新我的答案以包含它。
      猜你喜欢
      • 1970-01-01
      • 2012-10-22
      • 1970-01-01
      • 1970-01-01
      • 2015-04-30
      • 2013-08-06
      • 2017-05-10
      • 2013-06-12
      • 1970-01-01
      相关资源
      最近更新 更多