Sự khác biệt giữa các | và || hay khai thác?


300

Tôi đã luôn luôn sử dụng ||(hai ống dẫn) trong các biểu thức OR, cả trong C # và PHP. Thỉnh thoảng tôi thấy một đường ống duy nhất được sử dụng : |. Sự khác biệt giữa hai tập quán đó là gì? Có bất kỳ cảnh báo nào khi sử dụng cái này hay cái kia có thể hoán đổi cho nhau không?

Câu trả lời:


488

Cũng giống như toán tử &&&toán tử, Toán tử kép là toán tử "ngắn mạch".

Ví dụ:

if(condition1 || condition2 || condition3)

Nếu điều kiện 1 là đúng, điều kiện 2 và 3 sẽ KHÔNG được kiểm tra.

if(condition1 | condition2 | condition3)

Điều này sẽ kiểm tra điều kiện 2 và 3, ngay cả khi 1 đã đúng. Vì điều kiện của bạn có thể là các chức năng khá tốn kém, bạn có thể tăng hiệu suất tốt bằng cách sử dụng chúng.

Có một cảnh báo lớn, NullReferences hoặc các vấn đề tương tự. Ví dụ:

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

Nếu lớp là null, câu lệnh if sẽ dừng sau class != nulllà false. Nếu bạn chỉ sử dụng &, nó sẽ cố gắng kiểm tra class.someVarvà bạn sẽ có được một thứ tốt đẹp NullReferenceException. Với Nhà điều hành Or có thể không phải là một cái bẫy nhiều vì không chắc bạn có thể kích hoạt điều gì đó xấu, nhưng đó là điều cần lưu ý.

Không ai từng sử dụng các toán tử đơn &hoặc |toán tử, trừ khi bạn có một thiết kế trong đó mỗi điều kiện là một hàm phải được thực thi. Nghe có vẻ như mùi thiết kế, nhưng đôi khi (hiếm khi) đó là một cách sạch sẽ để làm công cụ. Các &nhà điều hành không "chạy 3 chức năng, và nếu một trong số họ trả về false, thực hiện các khối khác", trong khi |không "chỉ chạy các khối khác nếu không trả lại false" - có thể hữu ích, nhưng như đã nói, thường đó là một thiết kế mùi.

Có một cách sử dụng thứ hai của toán tử |&toán tử: Hoạt động theo bitwise .


9
Vâng, tôi đã không tin điều đó cho đến khi tôi tạo ra một ứng dụng console - nhưng chúa tể tốt! Tại sao họ sẽ cho bạn sợi dây để treo mình! Tôi ghét điều đó về VB.NET - từ khóa OrElse và AndAlso!
Jarrod Dixon

24
Dạy mọi người sử dụng &|như các nhà khai thác có điều kiện là một hack, và sẽ khiến họ gặp rắc rối nếu họ cần sử dụng C / C ++: 1 && 2là đúng trong khi đó 1 & 2là sai.
BlueRaja - Daniel Pflughoeft

47
Đây không phải là hack, nó được chỉ định chính thức cho C # trong Phần 7.10.3 Toán tử logic Boolean: "Kết quả của x | y là đúng nếu x hoặc y là đúng. Nếu không, kết quả là sai." Cũng xem Phần 7.11 Toán tử logic có điều kiện: "Thao tác x | | y tương ứng với thao tác x | y, ngoại trừ việc y chỉ được ước tính nếu x sai." mà tiếp tục "hợp pháp hóa" | như một toán tử có điều kiện. Và những người sẽ sử dụng C / C ++ dù sao cũng sẽ gặp rắc rối nếu họ chỉ mù quáng cho rằng công cụ đó hoạt động như nhau. Như đã nói: Sử dụng | trong một tuyên bố if là một mùi thiết kế, nhưng một hoạt động hoàn toàn hợp pháp.
Michael Stum

9
Tôi chưa bao giờ nói nó không hợp pháp, chỉ là nó là một hack (bạn đang sử dụng &để truyền đạt một ý nghĩa khác với ý nghĩa của nó gần như luôn luôn: bitwise - và) .
BlueRaja - Daniel Pflughoeft

15
@ BlueRaja-DannyPflughoeft Gọi một tính năng tài liệu là hack khi tài liệu nói rằng nó được sử dụng, giống như nói bằng cách sử dụng câu lệnh chuyển đổi "hack khácif". Đây là một công cụ trong hộp công cụ, một công cụ đặc biệt hiếm khi được sử dụng, nhưng một công cụ không phải là ít.
Gent

80

| | là toán tử OR logic. Có vẻ như bạn cơ bản biết đó là gì. Nó được sử dụng trong các câu điều kiện như if, while, v.v.

condition1 || condition2

Đánh giá là đúng nếu một trong hai điều kiện1 HOẶC điều kiện2 là đúng.

| là toán tử bitwise OR. Nó được sử dụng để hoạt động trên hai số. Bạn xem xét từng bit của từng số riêng lẻ và, nếu một trong số các bit là 1 trong ít nhất một trong các số đó, thì bit kết quả cũng sẽ là 1. Đây là vài ví dụ:

A = 01010101
B = 10101010
A | B = 11111111

A = 00000001
B = 00010000
A | B = 00010001

A = 10001011
B = 00101100

A | B = 10101111

Hy vọng rằng có ý nghĩa.

Vì vậy, để trả lời hai câu hỏi cuối cùng, tôi sẽ không nói có bất kỳ cảnh báo nào ngoài "biết sự khác biệt giữa hai nhà khai thác." Chúng không thể thay thế cho nhau vì chúng làm hai việc hoàn toàn khác nhau.


Điều này giúp tôi hiểu cách ai đó đang sử dụng toán tử bitwise OR để hợp nhất các bộ lọc trong trình điều khiển Mongodb C #. gist.github.com/a3dho3yn/ cường
Donny V.

30

Một là "bitwise hoặc".

10011b | 01000b => 11011b

Cái khác là logic hay.

đúng hay sai => đúng


2
|cũng có thể được sử dụng trên boolcác loại mà không bị đoản mạch.
juharr

14

Câu hỏi hay. Hai toán tử này hoạt động giống nhau trong PHP và C #.

|là một chút HOẶC. Nó sẽ so sánh hai giá trị bằng bit của chúng. Ví dụ 1101 | 0010 = 1111. Điều này cực kỳ hữu ích khi sử dụng các tùy chọn bit. Ví dụ: Đọc = 01 (0X01) Viết = 10 (0X02) Đọc-Viết = 11 (0X03). Một ví dụ hữu ích sẽ là mở tập tin. Một ví dụ đơn giản sẽ là:

File.Open(FileAccess.Read | FileAccess.Write);  //Gives read/write access to the file

||là HOẶC logic. Đây là cách mà hầu hết mọi người nghĩ về OR và so sánh hai giá trị dựa trên sự thật của họ. Ví dụ: tôi đang đi đến cửa hàng hoặc tôi sẽ đi đến trung tâm mua sắm. Đây là một trong những thường được sử dụng trong mã. Ví dụ:

if(Name == "Admin" || Name == "Developer") { //allow access } //checks if name equals Admin OR Name equals Developer

Tài nguyên PHP: http://us3.php.net/lingu.operators.bitwise

Tài nguyên C #: http://msdn.microsoft.com/en-us/l Library / kxszd0kx (VS.71) .aspx

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


4
FWIW, về mặt kỹ thuật, trong C # |logic hoặc khi được áp dụng cho booleans . Như các trạng thái tham chiếu được liên kết của bạn. Trong thực tế, kết quả cuối cùng giống như khi nó là toán tử bit, bởi vì các giá trị bit của truefalsetheo đó một bit hoặc các giá trị của chúng tạo ra kết quả chính xác giống như logic hoặc không. Đó là (int)(bool1 | bool2)== ((int)bool1) | ((int)bool2).
ToolmakerSteve

4

Ví dụ đơn giản trong 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;
  }
}

đầu ra:

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

2
Tại sao bạn lại đưa ra một ví dụ java cho một câu hỏi thậm chí không đề cập đến java?
juharr

4

& - (Điều kiện 1 & Điều kiện 2): kiểm tra cả hai trường hợp ngay cả khi trường hợp đầu tiên là sai

&& - (Điều kiện 1 && Điều kiện 2): không bận tâm kiểm tra trường hợp thứ hai nếu trường hợp một là sai

&& - toán tử sẽ làm cho mã của bạn chạy nhanh hơn, chuyên nghiệp hơn và hiếm khi được sử dụng

| - (Điều kiện 1 | Điều kiện 2): kiểm tra cả hai trường hợp ngay cả khi trường hợp 1 là đúng

| | - (Điều kiện 1 | | Điều kiện 2): không bận tâm kiểm tra trường hợp thứ hai nếu trường hợp thứ nhất là đúng

| | - toán tử sẽ làm cho mã của bạn chạy nhanh hơn, chuyên nghiệp | hiếm khi được sử dụng


2
rarely used? Tất cả phụ thuộc vào những gì bạn muốn hoặc cần làm.
Emaborsa

1
Tuyệt quá! Ngắn gọn và ngọt ngào, tôi sẽ loại bỏ "| hiếm khi được sử dụng" và "& hiếm khi được sử dụng" bởi vì, như Emaborsa nói, nó thực sự phụ thuộc vào những gì bạn muốn hoặc cần làm.
Iannick

0

Ống đơn, |, là một trong những toán tử bitwise .

Từ Wikipedia:

Trong họ ngôn ngữ lập trình C, toán tử bitwise OR là "|" (ống). Một lần nữa, toán tử này không được nhầm lẫn với đối tác "logic hoặc" Boolean của nó, coi toán hạng của nó là các giá trị Boolean và được viết "||" (hai ống).


0

Theo định nghĩa toán học của họ, OR và AND là các toán tử nhị phân; họ xác minh các điều kiện LHS và RHS bất kể, tương tự như | và &.

| | và && thay đổi các thuộc tính của toán tử OR và AND bằng cách dừng chúng khi điều kiện LHS không được đáp ứng.


-1

| toán tử thực hiện một bit HOẶC của hai toán hạng của nó (có nghĩa là cả hai bên phải ước tính thành false để nó trả về false) trong khi | | toán tử sẽ chỉ đánh giá toán tử thứ hai nếu cần.

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

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


Nếu bạn thực sự đọc những bài viết đó, bạn sẽ thấy rằng họ đang đề cập đến các toán tử bitwise
johnc

Đó không phải là ý nghĩa của bitwise.
juharr

-1

Các ống singe "|" là "bitwise" hoặc và chỉ nên được sử dụng khi bạn biết bạn đang làm gì. Ống đôi "||" là một logic hoặc, và có thể được sử dụng trong các câu lệnh logic, như "x == 0 || x == 1".

Đây là một ví dụ về những gì bitwise hoặc làm: if a = 0101 và b = 0011, thì a | b = 0111. Nếu bạn đang xử lý một hệ thống logic xử lý bất kỳ giá trị khác nào là đúng, thì bitwise hoặc sẽ hoạt động theo cách tương tự như logic hoặc, nhưng đối tác của nó (bitwise và, "&") sẽ KHÔNG. Ngoài ra bitwise hoặc không thực hiện đánh giá ngắn mạch.


'|' cũng có thể được sử dụng trên boolcác loại mà không bị đoản mạch.
juharr

-2

Một ống đơn (|) là toán tử bitwise OR .

Hai ống (||) là toán tử OR logic.

Chúng không thể thay thế cho nhau.


1
Nếu bạn bỏ qua hoạt động bitwise, ống đôi là đánh giá lười biếng và ống đơn là tham lam, trong khu vực toán tử logic.
Alex
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.