Nhược điểm của các toán tử cấp bitle.
Bạn hỏi:
“Có lý do nào đó không sử dụng các toán tử Bitwise &
, |
và ^
cho '' giá trị bool trong C ++? ”
Có, các toán tử logic , đó là các toán tử boolean cấp cao được tích hợp sẵn !
, &&
và ||
cung cấp các ưu điểm sau:
Đảm bảo chuyển đổi các đối số thành bool
, tức là sang 0
và 1
giá trị thứ tự.
Đánh giá ngắn mạch đảm bảo trong đó đánh giá biểu hiện dừng lại ngay khi biết kết quả cuối cùng.
Điều này có thể được hiểu là một lôgic giá trị cây, với Đúng , Sai và Không xác định .
Tương đương có thể đọc được văn bản not
, and
và or
, ngay cả khi tôi không sử dụng chúng bản thân mình.
Như ghi chú đọc Antimon trong một chú thích cũng là nhà khai thác bitlevel có thẻ thay thế, cụ thể là bitand
, bitor
, xor
và compl
, nhưng theo ý kiến của tôi đây là ít có thể đọc hơn and
, or
và not
.
Nói một cách đơn giản, mỗi ưu điểm như vậy của các toán tử cấp cao là một nhược điểm của các toán tử cấp bit.
Đặc biệt, vì các toán tử bitwise thiếu chuyển đổi đối số thành 0/1 nên bạn sẽ nhận được ví dụ 1 & 2
→ 0
, while 1 && 2
→ true
. Ngoài ra ^
, bitwise độc quyền hoặc, có thể hoạt động sai theo cách này. Được coi là giá trị boolean 1 và 2 là giống nhau true
, nhưng được coi là bitpatterns thì chúng khác nhau.
Cách diễn đạt logic hoặc / hoặc trong C ++.
Sau đó, bạn cung cấp một chút thông tin cơ bản cho câu hỏi,
“Đôi khi tôi gặp phải những tình huống mà tôi muốn chính xác một trong hai điều kiện là true (XOR), vì vậy tôi chỉ cần ném toán tử ^ vào một biểu thức điều kiện.”
Vâng, các toán tử bitwise có mức độ ưu tiên cao hơn các toán tử logic. Điều này đặc biệt có nghĩa là trong một biểu thức hỗn hợp, chẳng hạn như
a && b ^ c
bạn nhận được kết quả có lẽ bất ngờ a && (b ^ c)
.
Thay vào đó chỉ viết
(a && b) != c
diễn đạt ngắn gọn hơn ý của bạn.
Đối với nhiều đối số hoặc / hoặc không có toán tử C ++ nào thực hiện công việc. Ví dụ, nếu bạn viết a ^ b ^ c
hơn mà không phải là một biểu hiện nói rằng “một trong hai a
, b
hoặc c
là đúng”. Thay vào đó nó nói, “Một số lẻ của a
, b
và c
là đúng sự thật”, đó có thể là 1 trong số họ hoặc tất cả 3 ...
Để bày tỏ sự chung hoặc / hoặc khi a
, b
và c
là kiểu bool
, chỉ cần ghi
(a + b + c) == 1
hoặc, với các bool
đối số không , hãy chuyển đổi chúng thành bool
:
(!!a + !!b + !!c) == 1
Sử dụng &=
để tích lũy kết quả boolean.
Bạn nói rõ thêm,
“Đôi khi tôi cũng cần tích lũy các giá trị Boolean &=
và |=?
có thể khá hữu ích.”
Vâng, điều này tương ứng với việc kiểm tra xem tất cả hoặc bất kỳ điều kiện nào tương ứng được thỏa mãn hay không, và định luật de Morgan cho bạn biết cách đi từ điều này đến điều kiện khác. Tức là bạn chỉ cần một trong số chúng. Về nguyên tắc, bạn có thể sử dụng *=
như một người điều hành &&=
(đối với George Boole đã phát hiện ra, logic AND rất dễ được biểu thị dưới dạng phép nhân), nhưng tôi nghĩ rằng điều đó sẽ gây rắc rối và có thể đánh lừa những người bảo trì mã.
Cũng xem xét:
struct Bool
{
bool value;
void operator&=( bool const v ) { value = value && v; }
operator bool() const { return value; }
};
#include <iostream>
int main()
{
using namespace std;
Bool a = {true};
a &= true || false;
a &= 1234;
cout << boolalpha << a << endl;
bool b = {true};
b &= true || false;
b &= 1234;
cout << boolalpha << b << endl;
}
Đầu ra với Visual C ++ 11.0 và g ++ 4.7.1:
thật
sai
Lý do cho sự khác biệt trong kết quả là bitlevel &=
không cung cấp chuyển đổi sang đối bool
số bên phải của nó.
Vì vậy, bạn mong muốn kết quả nào trong số những kết quả này &=
?
Nếu là trước, true
thì tốt hơn nên xác định một toán tử (ví dụ như ở trên) hoặc hàm được đặt tên, hoặc sử dụng một chuyển đổi rõ ràng của biểu thức bên phải hoặc viết cập nhật đầy đủ.