&&
是逻辑AND,||
是逻辑OR
例如,在C#中,
using System;
class Program {
static void Main() {
Console.WriteLine("Enter a number");
int num = int.Parse(Console.ReadLine());
if(num>=0&&num<=10)
Console.WriteLine("Hi");
else
Console.WriteLine("Hello");
}
}
现在对于&&
只有两个条件都为真,那么if
块被执行,否则else
块被执行。
所以对于输入2
条件num>=0
和num<=10
都是true
。所以条件num>=0&&num<=10
是true
和if
语句被执行。得到输出Hi
。
对于输入-2
条件num<=10
是true
但条件num>=0
是false
。由于两个条件都应该为真,因此条件num>=0 && num<=10
为false,而不是for
语句else
语句被执行。所以输出是Hello
。
对于输入12
条件num>=0
是true
但条件num<=10
是false
。由于两个条件都应该为真,因此条件num>=0 && num<=10
为false,而不是for
语句else
语句被执行。所以输出是Hello
。
现在,在这种情况下,如果第一个条件num>=0
出来是flase
编译器不检查第二个条件num<=10
,因为在&&
的情况下如果两个条件都是true
,那么num>=0&&num<=10
才是true
。
现在考虑以下程序 -
using System;
class Program {
static void Main() {
Console.WriteLine("Enter a number");
int num = int.Parse(Console.ReadLine());
if(num>=0&num<=10)
Console.WriteLine("Hi");
else
Console.WriteLine("Hello");
}
}
这里没有&&
,而是给出了&
输出将与&&
和&
的真值表相同。
但在这里,在评估条件num>=0&num=<10
期间,如果输入是-2
,那么第一个条件num>=0
是false
。但与&&
不同,即使在第一个条件是false
第二个条件num<=10
被评估,然后控制传递到下一个语句。
逻辑OR也是如此;考虑以下C#示例 -
using System;
class Program {
static void Main() {
Console.WriteLine("Enter a number");
int num = int.Parse(Console.ReadLine());
if(num<=0||num>=10)
Console.WriteLine("Hi");
else
Console.WriteLine("Hello");
}
}
如果输入是-2
,第一个条件num<=0
是true
,第二个条件num>=10
是false
。因为在||
num<=0||num>=10
是true
,如果两个陈述中的任何一个是true
,那么if
块被执行并且输出是Hi
。
如果输入是12
第一个条件num<=0
是false
但第二个条件num>=10
是true
。对于||
num<=0||num>=10
是true
,如果任一条件是true
,所以if
块被执行,输出是Hi
。
如果输入是2
第一个条件num<=0
是false
。第二个条件num>=10
也是假的。由于两个条件都是false
num<=0||num>=10
是flase
和else
块被执行。因此输出是Hello
。
现在考虑以下程序 -
using System;
class Program {
static void Main() {
Console.WriteLine("Enter a number");
int num = int.Parse(Console.ReadLine());
if(num<=0|num>=10)
Console.WriteLine("Hi");
else
Console.WriteLine("Hello");
}
}
这里使用的不是||
|
。这两个程序都生成与||
和|
的真值表相同的输出。
但是当使用||
并且如果输入是-2
时,首先条件num<=0
是true
。因为num<=0||num>=10
是true
要么条件需要true
和第一个条件num<=0
已经是真的,编译器不检查第二个条件num>=10
但是当使用|
时,输入是-2
,即使在评估第一个条件num<=0
为真之后,编译器检查第二个条件num>=10
让我们考虑以下示例 -
#include <stdio.h>
int main() {
int a, b, c;
a = -1;
b = 0;
c = ++a && ++b;
printf("a = %d, b = %d, c = %d\n", a, b, c);
return 0;
}
预期产量:
a = 0, b = 1, c = 0
实际输出:
a = 0, b = 0, c = 0
这是因为在c = ++a && ++b;
语句中,当a
的值增加1
时,它的新值是0
。 0
被评估为false
。在&&
,如果第一个条件或第二个条件是false
,整个条件是false
。所以这里++a
被评估为false
,条件++b
永远不会被编译器检查。所以b
永远不会增加,它的价值保持0
现在考虑以下示例 -
#include <stdio.h>
int main() {
int a, b, c;
a = 0;
b = 10;
c = ++a || ++b;
printf("a = %d, b = %d, c = %d\n", a, b, c);
return 0;
}
预期产量:
a = 1, b = 11, c = 1
实际输出:
a = 1, b = 10, c = 1
在声明中
c = ++a || ++b;
++a
是1
,1
被评为true
。在||
,如果第一个条件或第二个条件是true
,整个条件是true
。这里因为第一个条件++a
为真,所以编译器从不检查第二个条件++b
。所以b
的价值永远不会增加并保持10
。
现在,我的问题 -
&
和|
在C中是否有效,以便可以避免短路?bool
只能是true
,false
或null
。不像C 0
不是false
和所有non-zero
值不是true
。所以C#中永远不会发生短路。所以在C#中,&
和|
的效用是什么?以下是您的问题的答案:
是&和|在C中有效可以避免短路?
不。与C#逻辑对应物相比,C中的&
和|
运算符意味着不同的东西。
在C中,&
和|
是按位运算符。他们将根据操作员评估两侧并合并结果值的位。之后,如果在逻辑上下文中使用结果值,则将其处理为0 = false,其他值= true。
这与C#的短路逻辑运算符不同。
在C#中,bool只能是true,false或null。与C 0不同,并非所有非零值都不为真。所以C#中永远不会发生短路。
那么在C#中,&和|的效用是什么?
&
和|
作为C#逻辑运算符的目的是支持非短路评估。
举个例子:
// s is string
if (s != null && s.Length > 0) { ... }
这里,如果s
确实是null
,则第一个操作数的值是false
,因此整个表达式永远不能是true
,因此第二个操作数s.Length > 0
不被评估。
与此形成鲜明对比:
if (s != null & s.Length > 0) { ... }
注意我在这里切换到非短路&
操作员。这里,如果s
为null,则仍将评估两个操作数,并且代码将抛出NullReferenceException
。
在某些情况下,即使您知道无论第二个操作数是什么意思,结果都不会是假的,您可能会对双方进行评估,这可能是有益的。在这些情况下,您将使用非短路运算符。
在C中,运算符意味着:
|
=按位OR运算符&
=按位AND运算符||
=短路的逻辑OR运算符&&
=短路的逻辑AND运算符在C#中,运算符意味着:
|
=按位OR运算符,如果应用于整数,逻辑非短路OR运算符,如果应用于bools&
=按位AND运算符,如果应用于整数,逻辑非短路AND运算符,如果应用于bools||
=短路的逻辑OR运算符&&
=短路的逻辑AND运算符单字符运算符&
和|
分别是按位AND和OR。它们与布尔测试无关,使用短路&&
和||
。
我不太明白你的问题:
&和|不是逻辑运算符。将它们用作逻辑运算符利用了C语言特性,即零为假,非零为真(这不是完全类型安全的)。
C#是一种完全类型安全的语言,因此逻辑表达式必须是布尔值。这意味着逻辑运算符仅适用于布尔值(&&,||),而按位运算仅适用于整数类型(&,|,^)
基本上,&,|的目的和^运算符不是在C中进行逻辑测试,只是语言的类型不安全,足以允许它作为副作用。
编辑:我更正,(&,|)在C#中也显然是有效的逻辑运算符(只是&&,||的简写)