1

我在这个编程世界中很新,我的问题可能听起来很傻,但任何人都可以解释以下两个代码之间的区别。

代码 1

    int yr;
    printf("enter the respective year=\n");
    scanf("%d", &yr);
    if(yr%400==0 || yr%100!=0 && yr%4==0)
        printf("It is a leap year\n");
    else
        printf("It is not a leap year\n");

    return 0;

代码 2

    int yr;
    printf("enter the respective year=\n");
    scanf("%d", &yr);
    if((yr%100==0 && yr%400==0) || yr%4==0)
        printf("It is a leap year\n");
    else
        printf("It is not a leap year\n");

    return 0;

我认为两者都应该运行良好,但是当我执行它们时,只有代码 1 给出了正确的答案。

4

3 回答 3

2

if 语句中的条件

if(yr%400==0 || yr%100!=0 && yr%4==0)

可以使用括号等价地重写

if ( ( yr%400==0 ) || ( yr%100!=0 && yr%4==0 ) )

意味着闰年是可以被 整除4004同时不能被整除的年份100

例如,年份1900不是闰年,因为它不能被 整除,400另一方面又能被 整除100

此 if 语句中的条件

if((yr%100==0 && yr%400==0) || yr%4==0)

意味着任何可被 4 整除的年份都是闰年,因为第二个子表达式yr%4==0对于任何可被 4 整除的年份总是产生逻辑真。因此,第一个子表达式的逻辑结果是什么甚至是不重要的,(yr%100==0 && yr%400==0)因为任何数字能被 100 整除,400 能同时被 4 整除。

所以第二个 if 语句在逻辑上是错误的。它接受year1900 年作为闰年。

于 2021-05-18T16:52:44.463 回答
0

表达式

(yr%400==0 || yr%100!=0 && yr%4==0)   /* (yr%400==0 || (  yr%100!=0 && yr%4==0))*/

( yr%100!=0 && yr%4==0 || yr%400==0 )   /* ( (yr%100!=0 && yr%4==0) || yr%400==0 )*/

是正确的,但为了避免混淆最好使用括号。如评论中所示,两者的评估(分组计算)不同。评估顺序基于运算符优先级规则(&& 优先于 ||)。

于 2021-05-18T18:57:48.287 回答
0

有两个复杂的冲突:闰年规则本身和逻辑运算符。&&绑定比更紧密,但这||甚至不是更深层次的问题。

A(嵌套)if...else可能是矫枉过正。

条件?:似乎很完美。我可以省略==0加号 NOT !=。只需将 0/1 放在正确的位置即可。这给出了一个常规模式:

int isleap(int y) {

    return
    y%4 ?            // normal year?
      0              // done
      : y%100 ?      // Candidate. Not a century?
         1           // normal leap
         : y%400 ?   // Century. normal one?
            0        // 100 normal century   
            : 1      // 400 special century
    ;                     // return's semicolon
}

三元条件表达式介于逻辑表达式和 if 语句之间。使用逻辑表达式,将两个“1”案例安全地收集在一起有点困难。

“哦,但这需要更多的台词。”

是的。还是您想定期复制粘贴该单行逻辑表达式?而且它可以放在一条线上,看起来只比 &&||-versions 差 20%。

(没有人真正问过,自言自语)

“哦,这是一个完整的功能”

inline如果速度很重要,它是一个官方的函数说明符。


为什么我说的是日志。表达式。在这种情况下很棘手。“标准” 4-100-400-no-parens-middle-not 公式:

 return y%4 == 0 && y%100 != 0 || y%400 == 0;

使编译器建议&&零件周围的括号。但即使使用错误的括号,您也会得到正确的结果。集合论?倒置双重异常?

于 2021-05-18T20:26:32.173 回答