"|" 和 "||" 运算符有什么区别?"

378

我一直在C#和PHP中使用两个竖线||来表示OR表达式。有时,我看到只使用一个竖线|。这两种用法有什么区别?在使用其中一种时是否有任何注意事项或它们可以互换使用?

12个回答

579
&& 运算符和 & 运算符一样,双运算符也是一个“短路”运算符。
例如:
if(condition1 || condition2 || condition3)

如果条件1为真,则不会检查条件2和3。

if(condition1 | condition2 | condition3)

即使条件1已经为真,此代码将检查条件2和条件3。由于您的条件可能是相当昂贵的函数,因此使用它们可以获得良好的性能提升。

但需要注意的是,存在空引用或类似问题。例如:

if(class != null && class.someVar < 20)

如果类为null,if语句将在class != null为false后停止。如果您仅使用&,它将尝试检查class.someVar,并返回一个漂亮的NullReferenceException。对于或运算符而言,它可能不会是一个陷阱,因为不太可能触发什么糟糕的事情,但是这是需要记住的。

没有人会使用单个的&|操作符,除非您拥有每个条件都必须被执行的函数设计。听起来像是一个设计上的问题,但有时候(很少)这是一种清晰的处理方式。&操作符表示“运行这3个函数,如果其中一个返回false,则执行else块”,而|则表示“只有当所有函数都返回true时才执行else块” - 可以派上用场,但通常是设计中的问题。

然而,还有第二种使用|&运算符的方法:位运算


“and” 和 “or” 不是短路计算吗? - xeruf

91

||是逻辑或运算符。从你的描述中看起来,你基本知道它是什么。它通常用于条件语句中,例如if、while等。

condition1 || condition2

如果条件1或条件2为真,则结果为true。

|是按位OR运算符。它用于对两个数字进行运算。您可以单独查看每个数字的每个位,如果其中一个数字中的至少一个位上为1,则最终位也将为1。以下是几个示例:

A = 01010101
B = 10101010
A | B = 11111111

A = 00000001
B = 00010000
A | B = 00010001

A = 10001011
B = 00101100

A | B = 10101111

希望这样说是有意义的。



因此,为了回答最后两个问题,我不会说除了“知道这两个运算符的区别”之外还有任何注意事项。它们不能互换,因为它们执行完全不同的操作。


这帮助我理解了有人如何使用位或运算符在Mongodb C#驱动程序中合并过滤器。https://gist.github.com/a3dho3yn/91dcc7e6f606eaefaf045fc193d3dcc3#combine-filters - Donny V.
4
“它用于操作两个数字”这个描述不准确/不完整。在C#中,if (true | false)是完全有效的。 - arkon
@arkon,如果你按位操作,1代表真,0代表假。所以,这些布尔值实际上可以被看作是零和一。你不能执行"str1" | "str2",对吗? - Jamshaid K.

36

其中一个是“位或”。

10011b | 01000b => 11011b

另一个是逻辑或。

true or false => true


3
“|”符号也可以用于布尔类型而不会发生短路现象。 - juharr
对于不熟悉位运算符的人来说,得到这个结果示例是因为使用OR比较将每个列的每个位行与其他位行进行了测试。https://learn.microsoft.com/en-us/cpp/c-language/c-bitwise-operators - Liam Pillay

20
好问题。这两个运算符在PHP和C#中的工作方式相同。 |是按位或运算符。它将通过比较两个值的位来进行运算。例如,1101 | 0010 = 1111。在使用位选项时,这非常有用。例如,读取= 01(0X01),写入= 10(0X02),读写= 11(0X03)。一个有用的例子是打开文件。一个简单的例子如下:
File.Open(FileAccess.Read | FileAccess.Write);  //Gives read/write access to the file
|| 是一个逻辑或运算符。这是大多数人对于或的理解方式,它根据两个值的真实性进行比较。例如:我要去商店或者我要去购物中心。这是在代码中最常用的一种方式。例如:
if(Name == "Admin" || Name == "Developer") { //allow access } //checks if name equals Admin OR Name equals Developer

PHP 资源: https://www.php.net/language.operators.bitwise

C# 资源: http://msdn.microsoft.com/en-us/library/kxszd0kx(VS.71).aspx

http://msdn.microsoft.com/en-us/library/6373h346(VS.71).aspx


4
就技术而言,在 C# 中,当应用于布尔值时,| 是一个逻辑或。就像你引用的参考文献所述。实际上,结果与按位运算符相同,因为 truefalse 的按位值使得它们的值的按位或产生与逻辑或完全相同的结果。也就是说,(int)(bool1 | bool2) 等同于 ((int)bool1) | ((int)bool2) - ToolmakerSteve

19

& - (条件1 & 条件2):即使第一个条件为假,也会检查两种情况。

&& - (条件1 && 条件2):如果第一个条件为假,就不需要检查第二个条件了。

&& - 运算符将使您的代码运行更快,专业的程序员很少使用。

| - (条件1 | 条件2):即使条件1为真,也会检查两种情况。

|| - (条件1 || 条件2):如果第一个条件为真,则不必检查第二个条件。

|| - 运算符将使您的代码运行更快,专业的程序员很少使用 |。


4
“rarely used”?一切取决于您想要或需要做什么。 - Emaborsa
3
好的!简短明了,我会把“|很少使用”和“&很少使用”删除,因为正如Emaborsa所说,这取决于你想要或需要做什么。 - Iannick
我非常依赖位运算。在处理标志时,这些特定的运算符也非常有用。你把“人们很少使用它们”误解为“我很少使用它们”。 - arkon
1
“Is rarely used” 意味着 “很少使用”,因为在所有可能的情况下,“或”操作应该短路。 - Denis G. Labrecque

4

Java中的简单示例

public class Driver {

  static int x;
  static int y;

public static void main(String[] args) 
throws Exception {

System.out.println("using double pipe");
    if(setX() || setY())
        {System.out.println("x = "+x);
        System.out.println("y = "+y);
        }



System.out.println("using single pipe");
if(setX() | setY())
    {System.out.println("x = "+x);
    System.out.println("y = "+y);
    }

}

 static boolean setX(){
      x=5;
     return true;
  }
 static boolean setY(){
      y=5;
      return true;
  }
}

输出:

using double pipe
x = 5
y = 0
using single pipe
x = 5
y = 5

3
为什么你会在一个甚至没有提到Java的问题中举例Java呢? - juharr

0
根据它们的数学定义,OR和AND是二元运算符;它们无论如何都验证左侧和右侧条件,类似于|和&。 ||和&&通过在LHS条件未满足时停止它们来改变OR和AND运算符的属性。

0

单管符号 | 是按位运算符之一。

维基百科介绍:

在C语言家族中,按位 OR 运算符是“|”(单管)。再次强调,这个运算符不应该与它的布尔“逻辑或”对手混淆,后者将其操作数视为布尔值,并写成“||”(两个管道符号)。


-1

对于位运算符 | 和逻辑运算符 ||

OR

位运算符 & 和逻辑运算符 &&

它的意思是 if(a>b | a==0) 在这个语句中,首先会评估左边的 a>b,然后再评估 a==0,最后进行 | 操作。

但是在|| if a>b语句中,如果左边的条件 a>b 成立,则不会继续检查右边的条件。

对于 & 和 && 也是同样的道理

if(A>0 & B>0)

它会先评估左边的条件,然后再评估右边的条件,最后进行位运算 & 操作。

但是在(A>0 && B>0)语句中,如果左边的条件if(A>0) 不成立,程序将直接返回false;


-2

单竖线“|”是“按位或”操作符,只有在你知道自己在做什么时才应该使用。双竖线“||”是逻辑或操作符,可以用在逻辑语句中,例如“x == 0 || x == 1”。

以下是按位或的示例:如果a=0101和b=0011,则a|b=0111。如果你正在处理将任何非零视为真的逻辑系统,则按位或将像逻辑或一样起作用,但它的对应操作符(按位与“&”)则不会。此外,按位或不执行短路评估。


“|” 也可以用于 bool 类型而不进行短路。 - juharr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接