&& và || không logic nhưng toán tử có điều kiện?


62

Tôi là một chút bối rối bởi các tài liệu MSDN C # trong đó nêu rằng &|là nhà khai thác hợp lý và đó &&||là nhà khai thác có điều kiện.

Tôi liên tục gọi &&, ||!các nhà khai thác logic, vì vậy tôi sai?


4
Điều này có vẻ phi logic, nhưng có một sự khác biệt quan trọng giữa hai lớp và điều quan trọng là bạn không cho rằng, có thể |hoán đổi cho nhau ||, mặc dù trong nhiều trường hợp chúng có thể được thay thế mà không có thay đổi rõ ràng trong hành vi chương trình.
Daniel R Hicks

Câu trả lời:


120

Tôi là một chút bối rối bởi các tài liệu MSDN C # trong đó nêu rằng &|là nhà khai thác hợp lý và đó &&||là nhà khai thác có điều kiện. Tôi liên tục gọi &&, ||!các nhà khai thác logic, vì vậy tôi sai?

Không; bạn hoàn toàn đúng.

Có rất nhiều lỗi danh pháp nhỏ, chủ yếu là không quan trọng trong tài liệu MSDN; Tôi đã cố gắng đưa ra càng nhiều càng tốt, nhưng trong trường hợp nó không quá sai và gây hiểu lầm, thì đó không phải lúc nào cũng là cách sử dụng thời gian khôn ngoan. Đi đến đặc tả nếu bạn muốn một tuyên bố dứt khoát về tên của tính năng C #.

Vì vậy: cơ quan có liên quan là đặc tả C #, nêu trong phần 7.11:

Các &, ^|các nhà khai thác này được gọi là các toán tử logic.

Sau đó, nó tiếp tục chia nhỏ các toán tử logic tích hợp thành các toán tử logic số nguyên, liệt kê, Boolean và nullable-Boolean. Ngoài ra còn có các toán tử logic do người dùng định nghĩa; xem thông số kỹ thuật để biết chi tiết

Trong phần 7.12, chúng ta có

Các toán tử &&||được gọi là các toán tử logic có điều kiện. Chúng cũng được gọi là các toán tử logic ngắn mạch của Wikipedia.

Vì vậy, tất cả chúng là các toán tử logic . Một số trong số họ là toán tử logicđiều kiện .

Điều gì làm cho các toán tử logic có điều kiện có điều kiện ? Người ta có thể đoán rằng đó là vì chúng thường được sử dụng trong các câu điều kiện ( if) hoặc biểu thức điều kiện ( ? :). Lý do thực sự được đưa ra bởi đặc tả:

Các toán tử &&||toán tử là các phiên bản có điều kiện của các toán tử &|toán tử: Thao tác x && ytương ứng với thao tác x & y, ngoại trừ chỉ yđược đánh giá nếu xkhông sai. Hoạt động x || ytương ứng với hoạt động x | y, ngoại trừ chỉ yđược đánh giá nếu xkhông đúng.

Do đó, các toán tử logic có điều kiện được đặt tên vì toán hạng bên phải được đánh giá có điều kiện tùy thuộc vào giá trị của toán hạng bên trái.

Chúng ta có thể thấy điều này một cách sinh động hơn bằng cách lưu ý rằng các toán tử logic có điều kiện chỉ là "đường cú pháp" cho các biểu thức điều kiện . x && ychỉ đơn giản là một cách dễ chịu hơn để viết x ? y : false, và x || yđơn giản là một cách dễ chịu hơn để viết x ? true : y. Các biểu thức logic có điều kiện thực sự là các biểu thức điều kiện.

Ngoài ra còn có một hình thức do người dùng xác định của toán tử logic có điều kiện và nó hơi khó. Xem thông số kỹ thuật để biết chi tiết.

Đọc thêm, nếu chủ đề này làm bạn quan tâm:


3
@RobertHarvey: Đúng vậy, thực tế là & có thể hoạt động trên bools, kiểu số nguyên hoặc kiểu enum nhưng && chỉ hoạt động trên bools không liên quan gì đến việc chọn đặt tên một trong số chúng là dạng "có điều kiện" của toán tử. Toán tử điều kiện có điều kiện bởi vì nó có một nhánh có điều kiện trong ngữ nghĩa đánh giá của nó.
Eric Lippert

16
Tôi có ấn tượng rằng thuật ngữ "toán tử ngắn mạch" phổ biến hơn nhiều (và có lẽ ít mơ hồ hơn) so với "toán tử có điều kiện" theo nghĩa được mô tả.
Doc Brown

15
@DocBrown: Nó chắc chắn rất phổ biến, nhưng tôi luôn thấy cái tên đó gây hiểu lầm; có vẻ như đã được đặt ra bởi một người nghĩ rằng "ngắn mạch" và "cắt ngắn" để có được kết quả là như nhau. Đoản mạch là một lỗi nguy hiểm có thể nhanh chóng phá hủy hệ thống điện. Chúng tôi đặt tên các khối "không an toàn" trong C # "không an toàn" vì chúng nguy hiểm nếu sử dụng không đúng cách ; chúng ta đừng đưa ra những thứ dễ thương nhưng gây hiểu lầm cho những cái tên đầy giá trị. Đừng để tôi bắt đầu với toán tử Elvis. :-)
Eric Lippert

26
@EricLippert: Mặc dù "đoản mạch" nghe có vẻ đáng sợ đối với công chúng, tôi không nghĩ K & R đã nhầm lẫn về định nghĩa thực tế. Trong kỹ thuật điện, việc chập mạch không phải lúc nào cũng là một lỗi nguy hiểm, trên thực tế chúng ta luôn cố tình làm điều đó. Nó chỉ có nghĩa là cắt bỏ một phần không mong muốn của mạch bằng cách cho dòng điện đi theo con đường ngắn hơn.
hackerb9

1
@CortAmmon: Bạn sẽ muốn đọc đoạn văn sau trong đó tôi gọi rằng ngữ nghĩa toán tử do người dùng định nghĩa hơi khác nhau và bạn sẽ thấy thông số kỹ thuật để biết chi tiết.
Eric Lippert

27

Trong C # đây là tất cả các toán tử logic.

int x = 0xABCD & 0xFF // x == 0xCD

&&||được gọi là " toán tử logic có điều kiện " bởi vì chúng bị đoản mạch.

bool someOtherCondition = true;
if (x == 0xEF && someOtherCondition) // someOtherCondition is not evaluated, 
                                     // because x == 0xEF is false

Lưu ý rằng thuật ngữ này khác nhau từ ngôn ngữ này sang ngôn ngữ khác. Trong C và C ++ &&||chỉ là các toán tử logic. Trong Java &|được gọi là Toán tử Bitwise , trong khi C và C ++ phân loại chúng là Toán tử số học .


3
Có, Microsoft là cơ quan có thẩm quyền, nhưng tài liệu có thẩm quyền là đặc điểm kỹ thuật. Xem phần 7.12, Toán tử logic có điều kiện .
Eric Lippert

8
Đạo đức của câu chuyện là: điều quan trọng hơn là phải hiểu chính xác những gì các nhà khai thác này làm hơn là chính xác về tên của họ.
Robert Harvey

21
Tập trung vào những gì các nhà khai thác làm, và ngừng ám ảnh với các từ vựng. Xem thêm Đặt tên được coi là có hại .
Robert Harvey

4
+1. Tất cả mọi thứ được liệt kê trong câu hỏi chỉ là các toán tử lấy một hoặc hai biểu thức và đánh giá một giá trị. Các tính từ là chia tóc không cần thiết.
Blrfl


-2

Vấn đề là &|các toán tử bitwise , có nghĩa là chúng được áp dụng và mang lại các giá trị chuỗi bit. Và bitwise là một thuật ngữ rất được sử dụng trong các lập trình viên.

Ví dụ 0xff & 0x00 == 0x00, trong khi 0xff | 0x00 == 0xff.

&&||được áp dụng cho điều kiện, và mang lại giá trị thông thường của điều kiện; tức là truefalse.

Ví dụ true && false == false, trong khi true || false == true.

Do đó &&||có thể được gọi là toán tử có điều kiện , mặc dù đó không phải là một thuật ngữ thông thường giữa các lập trình viên.

Tất nhiên, mọi lập trình viên C, C ++, Java và C # đều biết tất cả điều đó. Nhưng tôi đoán rằng sự hiểu lầm xảy ra bởi vì "toán tử có điều kiện" không phải là một thuật ngữ thường xuyên được sử dụng bởi các lập trình viên.


5
Tất nhiên, mọi lập trình viên C, C ++, Java và C # đều biết tất cả điều đó. Đó là một điều rất thô lỗ để viết, ngụ ý OP là ngu ngốc. Tương tự bằng cách viết cho chúng tôi lập trình viên , bạn loại trừ OP. Xin đừng làm vậy.
DarkDust

1
Tôi không nghĩ rằng câu trả lời sau này của bạn mang lại bất kỳ giá trị gia tăng nào sau câu trả lời được chấp nhận của Eric Lippert, và hơn nữa là không chính xác theo nghĩa là không hiểu điểm của câu hỏi.
Honza Zidek

@DarkDust Mỗi lập trình viên C, C ++, Java và C # nên hiểu các toán tử đó. Đây không phải là thô lỗ mà là một thực tế .
Phil1970

1
@ Phil1970: OP dường như hiểu các nhà khai thác này, đó là về việc làm rõ việc đặt tên . Trong ánh sáng này, và đã nhấn mạnh các thuật ngữ có liên quan trong câu trả lời của Hilton, câu đó của anh ta có thể được hiểu là ý nghĩa mà mọi lập trình viên đều biết về những chi tiết đặt tên này, nhưng bạn thì không . Điều này sai (như có thể thấy trong các cuộc thảo luận của các câu trả lời khác) và cụm từ của nó là thô lỗ.
DarkDust

4
Gửi tất cả, tôi xin lỗi nếu câu trả lời của tôi trông thô lỗ. Tiếng Anh không phải là ngôn ngữ thứ nhất. Trong mọi trường hợp, tôi không bao giờ có ý ám chỉ rằng OP không phải là lập trình viên. Au contraire, tôi có nghĩa là anh ấy hoặc cô ấy bối rối bởi một cách đặt tên bất thường trong văn bản anh ấy hoặc cô ấy đọc. Tất cả những gì tôi đã cố gắng làm là làm rõ việc đặt tên bất thường theo các đoạn chương trình.
Hilton Fernandes
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.