В чем разница между | и || или операторы?


300

Я всегда использовал ||(две трубы) в выражениях OR, как в C #, так и в PHP. Иногда я вижу единственную трубу используется: |. В чем разница между этими двумя способами? Есть ли какие-либо предостережения при использовании одного поверх другого или они взаимозаменяемы?

Ответы:


488

Как &и &&оператор and , двойной оператор является оператором «короткого замыкания».

Например:

if(condition1 || condition2 || condition3)

Если условие 1 истинно, условия 2 и 3 НЕ будут проверены.

if(condition1 | condition2 | condition3)

Это проверит условия 2 и 3, даже если 1 уже верно. Поскольку ваши условия могут быть довольно дорогими функциями, вы можете получить хороший прирост производительности, используя их.

Есть одна большая оговорка, NullReferences или подобные проблемы. Например:

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

Если class равен нулю, оператор if остановится после того, class != nullкак false. Если вы используете только &, он попытается проверить, class.someVarи вы получите хороший NullReferenceException. С оператором «Ор» это может быть не такой уж ловушкой, так как маловероятно, что вы вызовете что-то плохое, но об этом следует помнить.

Тем не менее, никто никогда не использует одиночный оператор &или |операторы, если только у вас нет схемы, в которой каждое условие является функцией, которая должна выполняться. Звучит как запах дизайна, но иногда (редко) это чистый способ делать вещи. &Оператор не «запустить эти 3 функции, и если один из них возвращает ложь, выполнить еще блок», в то время как |это «только запустить еще блок , если ни один возвращение ложным» - может быть полезным, но , как сказал, часто это дизайн запах.

Существует и второе использование оператора |and &: побитовые операции .


9
Да, я не верил в это, пока не создал консольное приложение - но, Господи! Зачем вам дать веревку, чтобы повеситься! Я ненавидел это за VB.NET - ключевые слова OrElse и AndAlso!
Джаррод Диксон

24
Обучение людей использовать &и |как условные операторы - это взлом, и они будут иметь проблемы, если им когда-либо понадобится использование C / C ++: 1 && 2true, а 1 & 2false.
BlueRaja - Дэнни Пфлюгофт

47
Это не хак, это официально указано для C # в Разделе 7.10.3 Булевы логические операторы: «Результат x | y равен true, если x или y равен true. В противном случае результат равен false». Также см. Раздел 7.11 Условные логические операторы: «Операция x || y соответствует операции x | y, за исключением того, что y вычисляется, только если x ложно». который далее "узаконивает" | как условный оператор. И люди, которые будут использовать C / C ++, все равно будут в беде, если просто слепо предположить, что все работает одинаково. Как сказано: Использование | в утверждении if - это запах дизайна, но совершенно законная операция.
Майкл Стум

9
Я никогда не говорил, что это не законно, просто это хак, который он есть (вы используете, &чтобы передать значение, отличное от того, что оно почти всегда означает: побитовый-и) .
BlueRaja - Дэнни Пфлюгофт

15
@ BlueRaja-DannyPflughoeft Называть документированную функцию хаком, когда в документации говорится, что она предназначена для использования, все равно, что сказать с помощью оператора switch «хак elseif». Это инструмент в ящике для инструментов, возможно, редко используемый специальный инструмент, но инструмент, тем не менее.
Гент

80

|| логический оператор ИЛИ Похоже, вы в основном знаете, что это такое. Используется в условных выражениях, таких как if, while и т. Д.

condition1 || condition2

Значение true, если либо условие1 ИЛИ условие2 верно.

| является побитовым оператором ИЛИ. Он используется для работы на двух номерах. Вы смотрите на каждый бит каждого числа в отдельности и, если один из битов равен 1 хотя бы в одном из чисел, то результирующий бит также будет равен 1. Вот несколько примеров:

A = 01010101
B = 10101010
A | B = 11111111

A = 00000001
B = 00010000
A | B = 00010001

A = 10001011
B = 00101100

A | B = 10101111

Надеюсь, это имеет смысл.

Поэтому, чтобы ответить на два последних вопроса, я бы не сказал, что есть какие-то предостережения, кроме «знайте разницу между двумя операторами». Они не взаимозаменяемы, потому что они делают две совершенно разные вещи.


Это помогло мне понять, как кто-то использует побитовый оператор OR для объединения фильтров в драйвере Mongodb C #. gist.github.com/a3dho3yn/…
Донни В.

30

Один из них - «побитовый или».

10011b | 01000b => 11011b

Другой логика или.

правда или ложь => правда


2
|также может использоваться на boolтипах без короткого замыкания.
juharr

14

Хороший вопрос. Эти два оператора работают одинаково в 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: http://us3.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
FWIW, Технически, в C # |это логично или применительно к логическим значениям . Как указано в вашей ссылке. На практике конечный результат такой же, как если бы он был побитовым оператором, потому что побитовые значения trueи falseтаковы, что побитовые или их значения дают точно такой же результат, как и логический. Это (int)(bool1 | bool2)== ((int)bool1) | ((int)bool2).
ToolmakerSteve

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

2
Почему бы вы дать пример Java для вопроса, который даже не упоминает Java?
juharr

4

& - (Условие 1 и Условие 2): проверяет оба случая, даже если первый неверен

&& - (Условие 1 && Условие 2): не беспокойтесь о проверке второго случая, если первый случай ложный

&& - оператор заставит ваш код работать быстрее, профессионально и редко используется

| - (Условие 1 | Условие 2): проверяет оба случая, даже если случай 1 истинен

|| - (Условие 1 || Условие 2): не беспокойтесь о проверке второго случая, если первый - правда

|| - оператор заставит ваш код работать быстрее, профессионально | редко используется


2
rarely used? Все зависит от того, что вы хотите или нужно сделать.
Емаборса

1
Большой! Короче говоря, я бы убрал слова «| редко используется» и «& редко используется», потому что, как сказала Эмаборса, это действительно зависит от того, что вы хотите или должны делать.
Янник

0

Одиночная труба, |, является одним из побитовых операторов.

Из Википедии:

В семействе языков программирования C побитовый оператор ИЛИ "|" (Труба). Опять же, этот оператор не следует путать с его логическим «логическим или» аналогом, который обрабатывает свои операнды как логические значения и записывается как «||» (две трубы).


0

По их математическому определению OR и AND являются бинарными операторами; они проверяют условия LHS и RHS независимо, аналогично | и &.

|| и && изменяют свойства операторов OR и AND, останавливая их, когда условие LHS не выполняется.


-1

| оператор выполняет побитовое ИЛИ своих двух операндов (то есть обе стороны должны иметь значение false, чтобы он возвращал false), в то время как || Оператор будет оценивать только второй оператор, если это необходимо.

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

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


Если бы вы на самом деле читали эти статьи, вы бы увидели, что они ссылаются на побитовые операторы
johnc

Это не то, что означает побитовое.
juharr

-1

Опорная труба "|" является «побитовым» или и должен использоваться только тогда, когда вы знаете, что делаете. Двойная труба "||" является логическим или, и может использоваться в логических утверждениях, таких как «x == 0 || x == 1».

Вот пример того, что поразрядно или делает: если a = 0101 и b = 0011, то a | b = 0111. Если вы имеете дело с логической системой, которая обрабатывает любое ненулевое значение как истинное, то побитовое или будет действовать так же, как логическое или, но его аналог (побитовое и, "&") не будет. Также побитовый или не выполняет оценку короткого замыкания.


'|' также может использоваться на boolтипах без короткого замыкания.
juharr

-2

Одиночная труба (|) является побитовым оператором ИЛИ .

Два канала (||) - логический оператор ИЛИ.

Они не являются взаимозаменяемыми.


1
Если вы игнорируете побитовую операцию, двойная труба является ленивой оценкой, а одиночная труба жадной в пределах области логического оператора.
Алекс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.