&& 运算符的行为类似于 ||操作员
&& operator behaves like || operator
我是初学者,我一直在尝试 运行 一个程序,打印从 1 到 N(用户输入)的所有数字,除了那些同时被 3 和 7 整除的数字.然而,我的代码所做的是它打印从 1 到 N 的数字,除了那些可以被 3 或 7 整除的数字。我检查了一段时间,我不知道它为什么这样做。请向我解释我要去哪里错了。
static void Main(string[] args)
{
int n = 0;
int a = 0;
n = Convert.ToInt32(Console.ReadLine());
while (a <= n)
{
a++;
if (a % 3 != 0 && a % 7 != 0)
{
Console.WriteLine(a);
}
}
Console.ReadKey();
}
当我将 if 语句的符号反转为 ==
时,&&
运算符正常工作,但如果符号为 !=
,它的行为就像 ||
操作员,这让我更加困惑。问题很可能是在条件中,但我看不出它有什么问题。
你应该阅读 De Morgan's laws
"not (A and B)" is the same as "(not A) or (not B)"
also,
"not (A or B)" is the same as "(not A) and (not B)".
当 a
不能被 3 (a % 3 != 0
) 整除且不能被 7 整除时,a % 3 != 0 && a % 7 != 0
为真
(a % 7 != 0
)。因此,所有可被 3 或 7 (3,6,7,9,12,14,...)
整除的 a
使整个表达式为假。你可以改写成 !(a % 3 == 0 || a % 7 == 0)
应该是:
if ( !(a % 3 == 0 && a % 7 == 0) )
{
Console.WriteLine(a);
}
确切的意思是:除了能同时被3和7整除的数以外的所有数。
您也可以改写为:
if ( a % 3 != 0 || a % 7 != 0 )
{
Console.WriteLine(a);
}
&& 与 ||
的行为不同
要了解差异,用更简单的表达式做一些测试可能会有所帮助:
if (true && false)
if (true || false)
因此,您的问题在于理解代码中的其他运算符(!= 和 %)。
通常有助于将条件拆分为更小的表达式,并附有解释:
bool divisbleBy3 = (a % 3 == 0);
bool divisbleBy7 = (a % 7 == 0);
if (divisbleBy3 && divisibleBy7)
{
// do not print
}
else
{
// print
}
"Except numbers that are divisible by 3 and 7 at the same time"可以细分如下:
"divisible by 3 and 7 at the same time"
可以表示为:
"(divisible by 3 and divisible by 7)"
"Except"
可以表示为"Not"
.
所以你得到:
Not (divisible by 3 and divisible by 7)
"divisible by 3" 是 (a % 3) == 0
"divisible by 7" 是 (a % 7) == 0
给予:
Not ( (a % 3) == 0 and (a % 7) == 0)
在 C# 中 Not
变为 !
并且 and
变为 &&
,因此您可以将整个内容用 C# 编写为:
if (!((a % 3) == 0 && (a % 7) == 0))
与你的错误比较:
if (a % 3 != 0 && a % 7 != 0)
后者不正确,因为它的意思是:
if (the number is not divisible by 3) and (the number is not divisible by 7
).
即意思是"Print the number if it is neither divisible by 3 nor divisible by 7"
,意思是"don't print the number if it's divisible by 3 or 7"
.
要了解原因,首先考虑数字 6:
6 is not divisible by 3? = false (because 6 *is* divisible by 3)
6 is not divisible by 7? = true (because 6 is *not* divisible by 7)
所以这解析为 if false and true
,当然是 false
。
此结果也适用于任何其他可被 3 整除的数字,因此不会打印可被 3 整除的数字。
现在考虑数字 14:
14 is not divisible by 3? = true (because 14 is *not* divisible by 3)
14 is not divisible by 7? = false (because 14 *is* divisible by 7)
所以这解析为 if true and false
,当然是 false
。
此结果也适用于任何其他可被 7 整除的数字,因此不会打印可被 7 整除的数字。
希望你现在能明白为什么它是错的。如果不是,请考虑这个等效示例:
假设我们有四个人,木匠汤姆、木匠迪克、屠夫哈利和屠夫汤姆。
这个问题等同于您要问的问题:
Name every person who is (not called Tom and is not a Butcher)
而且您应该能够看到这与询问相同:
Name every person except (anyone called Tom or anyone who is a Butcher)
在这两种情况下,答案都是木匠迪克。
你应该问的问题是:
Name every person except (anyone called Tom who is also a butcher)
答案是木匠汤姆、木匠迪克和屠夫哈利。
第二定律指出:
"not (A or B)" is the same as "(not A) and (not B)"
这相当于我上面的示例,其中:
Name every person except (anyone called Tom or anyone who is a Butcher)
相当于:
Name every person who is (not called Tom and is not a Butcher)
其中A是anyone called Tom
,B是anyone who is a butcher
,not
写成except
。
你说的:
if not (divisible by 3 and divisible by 7) then print
你写了什么:
if not divisible by 3 and not divisible by 7 then print
不是一回事。亚里士多德最先想到的,Augustus De Morgan 158年前就写了法则,将not运算符应用于操作数并反转逻辑运算:
if not divisible by 3 or not divisible by 7 then print
产生:
if (a % 3 != 0 || a % 7 != 0)
或者照你说的写:
if (!(a % 3 == 0 && a % 7 == 0))
a % b != 0
表示 "a is not divisible by b".
如果某物既不能被 3 整除又不能被 7 整除,则它不能被 整除。因此,如果它是 3 的倍数 或 7 的倍数,您的陈述将是错误的。
根据现实世界的事物来思考逻辑通常会有所帮助:
(请记住 true and false == false
和 true or false == true
)
The ocean is blue (a is divisible by 3).
The ocean is not yellow (a is not divisible by 7).
What you have:
The ocean is not blue and the ocean is not yellow - this is false (you want this to be true).
What you want:
The ocean is not (blue and yellow) - this is true (the ocean is only blue, not both blue and yellow).
The ocean is not blue or the ocean is not yellow - this is true (the ocean is not yellow).
最后 2 个语句的等价物是:
!(a % 3 == 0 && a % 7 == 0)
(a % 3 != 0 || a % 7 != 0)
您可以使用 De Morgan's laws.
将一个转换为另一个
如果您不知道如何实现算法,请尝试将其分解为 each 实现的明显正确的函数 part的算法。
您想 "print all the numbers from 1 to N (user input) except for those that are divisible by 3 and 7 at the same time." 老前辈可以使用逻辑运算符快速吐出正确且高效的实现。作为初学者,您可能会发现将其分解成多个部分会有所帮助。
// write out the highest level problem to solve, using functions as
// placeholders for part of the algorithm you don't immediately know
// how to solve
for ($x = 1; $x <= $N; $x++) {
if (is_not_divisible_by_3_and_7($x)) {
print "$x\n";
}
}
// then think about the function placeholders, writing them out using
// (again) function placeholders for things you don't immediately know
// how to do
function is_not_divisible_by_3_and_7($number) {
if (is_divisible_by_3_and_7($number)) {
return false;
} else {
return true;
}
}
// keep repeating this...
function is_divisible_by_3_and_7($number) {
if (is_divisible_by_3($number) && is_divisible_by_7($number)) {
return true;
} else {
return false;
}
}
// until you have the simplest possible functions
function is_divisible_by_3($number) {
if ($number % 3 === 0) {
return true;
} else {
return false;
}
}
function is_divisible_by_7($number) {
if ($number % 7 === 0) {
return true;
} else {
return false;
}
}
这更容易理解,因为每个函数只做一件事,而函数名恰好描述了那件事。这也满足了编程的第一条规则:代码正确.
然后您可以开始考虑使代码更好,其中更好的意思是:
- 更少的代码行
- 更少的计算
- 更多评论
将这种方法与上面的代码结合使用,一个明显的改进是用通用函数替换 is_divisible_by_3
和 is_divisible_by_7
:
function is_divisible_by_n($number, $divisor) {
if ($number % $divisor === 0) {
return true;
} else {
return false;
}
}
然后您可以用三元运算符替换所有大而笨重的 if x return true else return false
,这样您就可以:
function is_divisible_by_n($number, $divisor) {
return ($number % $divisor === 0) ? true : false;
}
function is_divisible_by_3_and_7($number) {
return (is_divisible_by_n($number, 3) && is_divisible_by_n($number, 7)) ? true : false;
}
function is_not_divisible_by_3_and_7($number) {
return (is_divisible_by_3_and_7($number)) ? false : true;
}
现在,请注意 is_not_divisible_by_3_and_7
看起来与 is_divisible_by_3_and_7
完全一样,只是 return 被切换了,因此您可以将它们合并为一个方法:
function is_not_divisible_by_3_and_7($number) {
// look how it changed here ----------------------------------------------VVVVV - VVVV
return (is_divisible_by_n($number, 3) && is_divisible_by_n($number, 7)) ? false : true;
}
现在,您可以利用比较本身 return 一个值的事实,而不是使用三元运算符:
function is_divisible_by_n($number, $divisor) {
// this expression returns a "truthy" value: true or false
// vvvvvvvvvvvvvvvvvvvvvvvvvv
return ($number % $divisor === 0);
}
function is_not_divisible_by_3_and_7($number) {
// also returns a truthy value, but inverted because of the !
// vvv
return ! (is_divisible_by_n($number, 3) && is_divisible_by_n($number, 7));
}
最后,您可以机械地用等效的逻辑操作替换函数调用:
for ($x = 1; $x <= $N; $x++) {
// all I did below was copy from the function, replace variable names
// v vvvvvvvvvvvvvv vvvvvvvvvvvvvv
if (! (($x % 3 === 0) && ($x % 7 === 0))) {
print "$x\n";
}
}
作为奖励积分,您可以应用 DeMorgan 规则,通过表达式分配 not:
for ($x = 1; $x <= $N; $x++) {
if ($x % 3 !== 0 || $x % 7 !== 0) {
print "$x\n";
}
}
此外,您可能会观察到两个互质数有公因数当且仅当它们有公因数 N 乘以 M,所以:
for ($x = 1; $x <= $N; $x++) {
if ($x % (3*7) !== 0) {
print "$x\n";
}
}
您可以通过使用您的语言的特性来进一步压缩表达式:
array_walk(
range(1, $N),
function ($x) {
if ($x % 21 !== 0) print "$x\n";
}
);
等等。关键是您首先要使代码正确,然后再使其变得更好。有时使代码正确意味着长时间的思考。有时它只是意味着以非常小、非常明确的步骤写出来。
查看条件语句的 Truth Table 你可以看到 if
X(NOT multiple of 3) Y(NOT multiple of 7) X && Y
true true 'a' printed as it is not a multiple of either
true false 'a' not printed, it is multiple of 7
false true 'a' not printed, it is multiple of 3
false false 'a' not printed, it is multiple of both
这就是为什么不打印所有 3 或 7 或 21 的倍数的原因。
你想要的:数字,即
- 不是一个(3和7的倍数)。那就是
- !(a%3==0 && a%7==0) 甚至进一步简化为
- !(a%21 == 0) 甚至
- (a%21 != 0)
你真正需要的是:
if ((a%21) != 0) Console.WriteLine(a);
解释:能同时被a和b整除的数本质上是可被 a 和 b 的 LCM 整除的数字。 因为 3 和 7 是质数,所以您基本上是在寻找不能被整除的数字3*7.
显然是&&和||不一样。
它指出:
如果(真&&假)=假
如果(真||假)=真
我是初学者,我一直在尝试 运行 一个程序,打印从 1 到 N(用户输入)的所有数字,除了那些同时被 3 和 7 整除的数字.然而,我的代码所做的是它打印从 1 到 N 的数字,除了那些可以被 3 或 7 整除的数字。我检查了一段时间,我不知道它为什么这样做。请向我解释我要去哪里错了。
static void Main(string[] args)
{
int n = 0;
int a = 0;
n = Convert.ToInt32(Console.ReadLine());
while (a <= n)
{
a++;
if (a % 3 != 0 && a % 7 != 0)
{
Console.WriteLine(a);
}
}
Console.ReadKey();
}
当我将 if 语句的符号反转为 ==
时,&&
运算符正常工作,但如果符号为 !=
,它的行为就像 ||
操作员,这让我更加困惑。问题很可能是在条件中,但我看不出它有什么问题。
你应该阅读 De Morgan's laws
当"not (A and B)" is the same as "(not A) or (not B)"
also,
"not (A or B)" is the same as "(not A) and (not B)".
a
不能被 3 (a % 3 != 0
) 整除且不能被 7 整除时,a % 3 != 0 && a % 7 != 0
为真
a % 7 != 0
)。因此,所有可被 3 或 7 (3,6,7,9,12,14,...)
整除的 a
使整个表达式为假。你可以改写成 !(a % 3 == 0 || a % 7 == 0)
应该是:
if ( !(a % 3 == 0 && a % 7 == 0) )
{
Console.WriteLine(a);
}
确切的意思是:除了能同时被3和7整除的数以外的所有数。
您也可以改写为:
if ( a % 3 != 0 || a % 7 != 0 )
{
Console.WriteLine(a);
}
&& 与 ||
的行为不同要了解差异,用更简单的表达式做一些测试可能会有所帮助:
if (true && false)
if (true || false)
因此,您的问题在于理解代码中的其他运算符(!= 和 %)。
通常有助于将条件拆分为更小的表达式,并附有解释:
bool divisbleBy3 = (a % 3 == 0);
bool divisbleBy7 = (a % 7 == 0);
if (divisbleBy3 && divisibleBy7)
{
// do not print
}
else
{
// print
}
"Except numbers that are divisible by 3 and 7 at the same time"可以细分如下:
"divisible by 3 and 7 at the same time"
可以表示为:
"(divisible by 3 and divisible by 7)"
"Except"
可以表示为"Not"
.
所以你得到:
Not (divisible by 3 and divisible by 7)
"divisible by 3" 是 (a % 3) == 0
"divisible by 7" 是 (a % 7) == 0
给予:
Not ( (a % 3) == 0 and (a % 7) == 0)
在 C# 中 Not
变为 !
并且 and
变为 &&
,因此您可以将整个内容用 C# 编写为:
if (!((a % 3) == 0 && (a % 7) == 0))
与你的错误比较:
if (a % 3 != 0 && a % 7 != 0)
后者不正确,因为它的意思是:
if (the number is not divisible by 3) and (the number is not divisible by 7
).
即意思是"Print the number if it is neither divisible by 3 nor divisible by 7"
,意思是"don't print the number if it's divisible by 3 or 7"
.
要了解原因,首先考虑数字 6:
6 is not divisible by 3? = false (because 6 *is* divisible by 3)
6 is not divisible by 7? = true (because 6 is *not* divisible by 7)
所以这解析为 if false and true
,当然是 false
。
此结果也适用于任何其他可被 3 整除的数字,因此不会打印可被 3 整除的数字。
现在考虑数字 14:
14 is not divisible by 3? = true (because 14 is *not* divisible by 3)
14 is not divisible by 7? = false (because 14 *is* divisible by 7)
所以这解析为 if true and false
,当然是 false
。
此结果也适用于任何其他可被 7 整除的数字,因此不会打印可被 7 整除的数字。
希望你现在能明白为什么它是错的。如果不是,请考虑这个等效示例:
假设我们有四个人,木匠汤姆、木匠迪克、屠夫哈利和屠夫汤姆。
这个问题等同于您要问的问题:
Name every person who is (not called Tom and is not a Butcher)
而且您应该能够看到这与询问相同:
Name every person except (anyone called Tom or anyone who is a Butcher)
在这两种情况下,答案都是木匠迪克。
你应该问的问题是:
Name every person except (anyone called Tom who is also a butcher)
答案是木匠汤姆、木匠迪克和屠夫哈利。
第二定律指出:
"not (A or B)" is the same as "(not A) and (not B)"
这相当于我上面的示例,其中:
Name every person except (anyone called Tom or anyone who is a Butcher)
相当于:
Name every person who is (not called Tom and is not a Butcher)
其中A是anyone called Tom
,B是anyone who is a butcher
,not
写成except
。
你说的:
if not (divisible by 3 and divisible by 7) then print
你写了什么:
if not divisible by 3 and not divisible by 7 then print
不是一回事。亚里士多德最先想到的,Augustus De Morgan 158年前就写了法则,将not运算符应用于操作数并反转逻辑运算:
if not divisible by 3 or not divisible by 7 then print
产生:
if (a % 3 != 0 || a % 7 != 0)
或者照你说的写:
if (!(a % 3 == 0 && a % 7 == 0))
a % b != 0
表示 "a is not divisible by b".
如果某物既不能被 3 整除又不能被 7 整除,则它不能被 整除。因此,如果它是 3 的倍数 或 7 的倍数,您的陈述将是错误的。
根据现实世界的事物来思考逻辑通常会有所帮助:
(请记住 true and false == false
和 true or false == true
)
The ocean is blue (a is divisible by 3).
The ocean is not yellow (a is not divisible by 7).What you have:
The ocean is not blue and the ocean is not yellow - this is false (you want this to be true).What you want:
The ocean is not (blue and yellow) - this is true (the ocean is only blue, not both blue and yellow).
The ocean is not blue or the ocean is not yellow - this is true (the ocean is not yellow).
最后 2 个语句的等价物是:
!(a % 3 == 0 && a % 7 == 0)
(a % 3 != 0 || a % 7 != 0)
您可以使用 De Morgan's laws.
将一个转换为另一个如果您不知道如何实现算法,请尝试将其分解为 each 实现的明显正确的函数 part的算法。
您想 "print all the numbers from 1 to N (user input) except for those that are divisible by 3 and 7 at the same time." 老前辈可以使用逻辑运算符快速吐出正确且高效的实现。作为初学者,您可能会发现将其分解成多个部分会有所帮助。
// write out the highest level problem to solve, using functions as
// placeholders for part of the algorithm you don't immediately know
// how to solve
for ($x = 1; $x <= $N; $x++) {
if (is_not_divisible_by_3_and_7($x)) {
print "$x\n";
}
}
// then think about the function placeholders, writing them out using
// (again) function placeholders for things you don't immediately know
// how to do
function is_not_divisible_by_3_and_7($number) {
if (is_divisible_by_3_and_7($number)) {
return false;
} else {
return true;
}
}
// keep repeating this...
function is_divisible_by_3_and_7($number) {
if (is_divisible_by_3($number) && is_divisible_by_7($number)) {
return true;
} else {
return false;
}
}
// until you have the simplest possible functions
function is_divisible_by_3($number) {
if ($number % 3 === 0) {
return true;
} else {
return false;
}
}
function is_divisible_by_7($number) {
if ($number % 7 === 0) {
return true;
} else {
return false;
}
}
这更容易理解,因为每个函数只做一件事,而函数名恰好描述了那件事。这也满足了编程的第一条规则:代码正确.
然后您可以开始考虑使代码更好,其中更好的意思是:
- 更少的代码行
- 更少的计算
- 更多评论
将这种方法与上面的代码结合使用,一个明显的改进是用通用函数替换 is_divisible_by_3
和 is_divisible_by_7
:
function is_divisible_by_n($number, $divisor) {
if ($number % $divisor === 0) {
return true;
} else {
return false;
}
}
然后您可以用三元运算符替换所有大而笨重的 if x return true else return false
,这样您就可以:
function is_divisible_by_n($number, $divisor) {
return ($number % $divisor === 0) ? true : false;
}
function is_divisible_by_3_and_7($number) {
return (is_divisible_by_n($number, 3) && is_divisible_by_n($number, 7)) ? true : false;
}
function is_not_divisible_by_3_and_7($number) {
return (is_divisible_by_3_and_7($number)) ? false : true;
}
现在,请注意 is_not_divisible_by_3_and_7
看起来与 is_divisible_by_3_and_7
完全一样,只是 return 被切换了,因此您可以将它们合并为一个方法:
function is_not_divisible_by_3_and_7($number) {
// look how it changed here ----------------------------------------------VVVVV - VVVV
return (is_divisible_by_n($number, 3) && is_divisible_by_n($number, 7)) ? false : true;
}
现在,您可以利用比较本身 return 一个值的事实,而不是使用三元运算符:
function is_divisible_by_n($number, $divisor) {
// this expression returns a "truthy" value: true or false
// vvvvvvvvvvvvvvvvvvvvvvvvvv
return ($number % $divisor === 0);
}
function is_not_divisible_by_3_and_7($number) {
// also returns a truthy value, but inverted because of the !
// vvv
return ! (is_divisible_by_n($number, 3) && is_divisible_by_n($number, 7));
}
最后,您可以机械地用等效的逻辑操作替换函数调用:
for ($x = 1; $x <= $N; $x++) {
// all I did below was copy from the function, replace variable names
// v vvvvvvvvvvvvvv vvvvvvvvvvvvvv
if (! (($x % 3 === 0) && ($x % 7 === 0))) {
print "$x\n";
}
}
作为奖励积分,您可以应用 DeMorgan 规则,通过表达式分配 not:
for ($x = 1; $x <= $N; $x++) {
if ($x % 3 !== 0 || $x % 7 !== 0) {
print "$x\n";
}
}
此外,您可能会观察到两个互质数有公因数当且仅当它们有公因数 N 乘以 M,所以:
for ($x = 1; $x <= $N; $x++) {
if ($x % (3*7) !== 0) {
print "$x\n";
}
}
您可以通过使用您的语言的特性来进一步压缩表达式:
array_walk(
range(1, $N),
function ($x) {
if ($x % 21 !== 0) print "$x\n";
}
);
等等。关键是您首先要使代码正确,然后再使其变得更好。有时使代码正确意味着长时间的思考。有时它只是意味着以非常小、非常明确的步骤写出来。
查看条件语句的 Truth Table 你可以看到 if
X(NOT multiple of 3) Y(NOT multiple of 7) X && Y
true true 'a' printed as it is not a multiple of either
true false 'a' not printed, it is multiple of 7
false true 'a' not printed, it is multiple of 3
false false 'a' not printed, it is multiple of both
这就是为什么不打印所有 3 或 7 或 21 的倍数的原因。
你想要的:数字,即
- 不是一个(3和7的倍数)。那就是
- !(a%3==0 && a%7==0) 甚至进一步简化为
- !(a%21 == 0) 甚至
- (a%21 != 0)
你真正需要的是:
if ((a%21) != 0) Console.WriteLine(a);
解释:能同时被a和b整除的数本质上是可被 a 和 b 的 LCM 整除的数字。 因为 3 和 7 是质数,所以您基本上是在寻找不能被整除的数字3*7.
显然是&&和||不一样。
它指出: 如果(真&&假)=假 如果(真||假)=真