【问题标题】:Precedence & Arity in strange statement奇怪的陈述中的优先级和Arity
【发布时间】:2015-03-18 13:40:48
【问题描述】:

这条语句的执行顺序和可能的结果是什么:leap = year%4 == 0;

(左边是赋值,右边是断言?) 摘自以下用于计算公历中任何日期的星期几的算法:

static char daytab[2][13] =
{
                {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
                {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
for (year = 1; year <= y; year++)
{
        leap  = year%4 == 0;
        if (year%100 == 0 && year%400 != 0)
                leap = 0;
        for (month = 1; month <= m; month++)
        {
                d += daytab[leap][month - 1];
                daystotal = 365*(year - 1) + (int)floor((year-1)/4)
                - (int)floor((year - 1)/100) + (int)floor((year - 1)/400) + d;
        }
}

【问题讨论】:

  • 首先评估year%4,然后与0进行比较,比较的赋值保存到leap

标签: c++ expression operator-precedence arity


【解决方案1】:

看这里operator precendence。将评估 year % 4,然后将结果与 0 进行比较,然后将结果分配给 leap 变量。

【讨论】:

    【解决方案2】:

    year % 4 == 0 等价于(year % 4) == 0,它取年除以 4 后的余数,然后将其与 0 进行比较并产生布尔结果——truefalse。你没有显示leap 的声明/定义,所以我们只能猜测它的类型。如果是bool,则该结果将直接分配给它。基于后面的代码:

    if (year%100 == 0 && year%400 != 0)
        leap = 0;
    

    看来leap 可能是其他某种算术类型(可能是int)。这很常见,尤其是在最初用 C90 编写的代码中,它没有布尔类型。

    在这种情况下,bool 将在分配之前进行转换。转换为算术类型时,false 转换为 0true 转换为 1(反之,0 转换为 false,任何其他值转换为 true) .

    所以,代码的效果基本上和类似:

    if ((year % 4) == 0)
        leap = 1;
    else
        leap = 0;
    

    ...或:

    leap = ((year % 4) == 0) ? 1 : 0;
    

    如果我写它,我想我可能会写成这样的代码:

    if ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0) )
        leap = 1;
    else
        leap = 0;
    

    ...或者(更有可能)只是:

    leap = ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0));
    

    至少对我来说,这更直接地说明了公历中“什么是闰年”的条件1。我想您可以通过以下方式将原始代码视为历史文物:它首先根据旧儒略历的规则计算是否是闰年,然后分别添加在公历中添加的规则。但是,如果有人真的想反映这段历史,他们可能应该包含一个注释,解释这就是代码按原样编写的原因。就目前而言,它不仅仅是计算正确的值,而是首先计算一个可能不正确的值,然后检查更多条件,然后再修补该值。


    1. 当然,例如:如果一年能被 4 整除,或者不能被 100 整除,或者也能被 400 整除,那么它就是闰年。例如,2000 年是闰年(能被 400 整除) 4 也能被 400 整除)但 1900 不能(能被 4 整除,但也能被 100 整除且不能被 400 整除)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-03
      • 1970-01-01
      • 1970-01-01
      • 2018-12-22
      相关资源
      最近更新 更多