闰年问题中逻辑运算符的使用
Use of logical operators in Leap year problem
我是这个编程世界的新手,我的问题听起来可能很愚蠢,但任何人都可以解释以下 2 个代码之间的区别。
代码 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 给出了正确答案。
if语句中的条件
if(yr%400==0 || yr%100!=0 && yr%4==0)
可以使用像
这样的括号等效地重写
if ( ( yr%400==0 ) || ( yr%100!=0 && yr%4==0 ) )
表示闰年是可以被400
整除或者可以被4
整除同时不能被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语句在逻辑上是错误的。它接受 year
1900 作为闰年。
表达式
(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 )*/
是正确的,但为了避免混淆最好使用括号。如评论中所示,两者的评估(分组计算)不同。评估顺序基于运算符优先级规则(&& 优先于 ||)。
存在两种复杂情况的冲突:闰年规则本身和逻辑运算符。 &&
比 ||
绑定更紧密,但这甚至不是更深层次的问题。
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-statement之间的逻辑表达式。使用逻辑表达式,很难将两个“1”的情况安全地收集在一起。
“哦,但这需要更多行。”
是的。还是要定期复制粘贴 one-line 逻辑表达式?而且可以排成一行,看起来只比&&||-版本差了20%
(真的没人问,自言自语)
“哦,这是一个完整的功能”
inline
是官方 function-specifier,如果速度很重要。
为什么我说的是日志。表达式在这种情况下很棘手。 “标准”4-100-400-no-parens-middle-not公式:
return y%4 == 0 && y%100 != 0 || y%400 == 0;
使编译器在 &&
部分周围建议 parens。但即使 parens 错误,您也会得到正确的结果。集合论?倒双异常?
我是这个编程世界的新手,我的问题听起来可能很愚蠢,但任何人都可以解释以下 2 个代码之间的区别。
代码 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 给出了正确答案。
if语句中的条件
if(yr%400==0 || yr%100!=0 && yr%4==0)
可以使用像
这样的括号等效地重写if ( ( yr%400==0 ) || ( yr%100!=0 && yr%4==0 ) )
表示闰年是可以被400
整除或者可以被4
整除同时不能被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语句在逻辑上是错误的。它接受 year
1900 作为闰年。
表达式
(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 )*/
是正确的,但为了避免混淆最好使用括号。如评论中所示,两者的评估(分组计算)不同。评估顺序基于运算符优先级规则(&& 优先于 ||)。
存在两种复杂情况的冲突:闰年规则本身和逻辑运算符。 &&
比 ||
绑定更紧密,但这甚至不是更深层次的问题。
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-statement之间的逻辑表达式。使用逻辑表达式,很难将两个“1”的情况安全地收集在一起。
“哦,但这需要更多行。”
是的。还是要定期复制粘贴 one-line 逻辑表达式?而且可以排成一行,看起来只比&&||-版本差了20%
(真的没人问,自言自语)
“哦,这是一个完整的功能”
inline
是官方 function-specifier,如果速度很重要。
为什么我说的是日志。表达式在这种情况下很棘手。 “标准”4-100-400-no-parens-middle-not公式:
return y%4 == 0 && y%100 != 0 || y%400 == 0;
使编译器在 &&
部分周围建议 parens。但即使 parens 错误,您也会得到正确的结果。集合论?倒双异常?