Trong khi các toán tử quan hệ (so sánh) có thể được sử dụng để kiểm tra xem một điều kiện cụ thể là đúng hay sai, chúng chỉ có thể kiểm tra một điều kiện tại một thời điểm. Thông thường chúng ta cần biết liệu nhiều điều kiện có đúng hay không. Ví dụ: để kiểm tra xem chúng ta có trúng xổ số hay không, chúng ta phải so sánh xem tất cả nhiều số chúng ta đã chọn có khớp với các số trúng hay không. Trong một cuộc xổ số với 6 số, điều này sẽ bao gồm 6 so sánh, tất cả đều phải đúng. Trong các trường hợp khác, chúng ta cần biết liệu bất kỳ một trong nhiều điều kiện là đúng. Ví dụ: chúng ta có thể quyết định bỏ qua công việc hôm nay nếu chúng ta ốm, hoặc nếu chúng ta quá mệt mỏi, hoặc nếu chúng ta trúng xổ số trong ví dụ trước. Điều này sẽ liên quan đến việc kiểm tra xem có bất kỳ 3 so sánh nào là đúng hay không.
Toán tử logic cung cấp cho chúng ta khả năng kiểm tra nhiều điều kiện.
C ++ có 3 toán tử logic:
Operator | Symbol | Form | Operation |
---|---|---|---|
Logical NOT | ! | !x | true nếu x là false, or false nếu x là true |
Logical AND | && | x && y | true nếu both x và y là true, false khi ngược lại |
Logical OR | || | x || y | true nếu either x or y là true, false khi ngược lại |
Nội dung chính
1. Logical NOT
Bạn đã chạy trên toán tử NOT đơn nguyên logic – Các giá trị Boolean. Chúng ta có thể tóm tắt những ảnh hưởng của logic NOT như vậy:
Logical NOT (operator !) | |
---|---|
Toán hạng | Kết quả |
true | false |
false | true |
Nếu toán hạng logic NOT đánh giá là đúng, logic NOT đánh giá thành sai. Nếu toán hạng logic NOT đánh giá là sai, logic NOT đánh giá là đúng. Nói cách khác, logic NOT lật giá trị Boolean từ true sang false và ngược lại.
Logic NOT thường được sử dụng trong các điều kiện:
/**
* Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
*
* @author cafedevn
* Contact: cafedevn@gmail.com
* Fanpage: https://www.facebook.com/cafedevn
* Instagram: https://instagram.com/cafedevn
* Twitter: https://twitter.com/CafedeVn
* Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/
bool tooLarge { x > 100 }; // tooLarge is true if x > 100
if (!tooLarge)
// do something with x
else
// print an error
Một điều cần cảnh giác là logic NOT có mức độ ưu tiên rất cao. Lập trình viên mới thường mắc lỗi sau
/**
* Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
*
* @author cafedevn
* Contact: cafedevn@gmail.com
* Fanpage: https://www.facebook.com/cafedevn
* Instagram: https://instagram.com/cafedevn
* Twitter: https://twitter.com/CafedeVn
* Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/
#include <iostream>
int main()
{
int x { 5 };
int y { 7 };
if (! x > y)
std::cout << "x is not greater than y\n";
else
std::cout << "x is equal to or greater than y\n";
return 0;
}
Chương trình này in:
x is equal to or greater than y
Nhưng x không bằng hoặc lớn hơn y, vậy làm thế nào điều này có thể? Câu trả lời là bởi vì toán tử logic NOT có độ ưu tiên cao hơn toán tử lớn hơn biểu thức! x > y thực sự đánh giá là (! x)> y. Vì x là 5 ,!X ước lượng thành 0 và 0> y là sai, nên câu lệnh khác thực thi!
Cách chính xác để viết đoạn trích trên là:
#include <iostream>
int main()
{
int x { 5 };
int y { 7 };
if (!(x > y))
std::cout << "x is not greater than y\n";
else
std::cout << "x is equal to or greater than y\n";
return 0;
}
Bằng cách này, x > y sẽ được đánh giá trước, và sau đó logic NOT sẽ lật kết quả Boolean.
Việc sử dụng logic NOT đơn giản, chẳng hạn như if (! Value) không cần dấu ngoặc đơn vì quyền ưu tiên không được sử dụng.
2. Logical OR
Toán tử logic OR được sử dụng để kiểm tra xem một trong hai điều kiện có đúng không. Nếu toán hạng bên trái ước tính là true hoặc toán hạng bên phải ước tính là true hoặc cả hai đều đúng, thì toán tử logic OR trả về true. Nếu không nó sẽ trả về false.
Logical OR (operator ||) | ||
---|---|---|
Toán hạng bên trái | Toán hạng bên phải | kết quả |
false | false | false |
false | true | true |
true | false | true |
true | true | true |
Ví dụ, hãy xem xét chương trình sau:
#include <iostream>
int main()
{
std::cout << "Enter a number: ";
int value {};
std::cin >> value;
if (value == 0 || value == 1)
std::cout << "You picked 0 or 1\n";
else
std::cout << "You did not pick 0 or 1\n";
return 0;
}
Trong trường hợp này, chúng ta sử dụng toán tử logic OR để kiểm tra xem điều kiện bên trái (value == 0) hay điều kiện bên phải (value == 1) là đúng. Nếu một trong hai (hoặc cả hai) là true, toán tử logic OR sẽ đánh giá là true, có nghĩa là câu lệnh if thực thi. Nếu cả hai đều không đúng, toán tử logic OR đánh giá thành false, có nghĩa là câu lệnh khác thực thi.
Bạn có thể xâu chuỗi nhiều câu lệnh logic OR:
if (value == 0 || value == 1 || value == 2 || value == 3)
std::cout << "You picked 0, 1, 2, or 3\n";
Các lập trình viên mới đôi khi nhầm lẫn toán tử logic OR (||) với toán tử OR bitwise (|). Mặc dù cả hai đều có OR trong tên, chúng thực hiện các chức năng khác nhau. Trộn chúng lên có thể sẽ dẫn đến kết quả không chính xác.
3. Logical AND
Toán tử logic AND được sử dụng để kiểm tra xem cả hai toán hạng có đúng không. Nếu cả hai toán hạng đều đúng, logic AND trả về true. Nếu không, nó trả về false.
Logical AND (operator &&) | ||
---|---|---|
Toán hạng bên trái | Toán hạng bên phải | Kết quả |
false | false | false |
false | true | false |
true | false | false |
true | true | true |
Ví dụ: chúng ta có thể muốn biết giá trị của biến x có nằm trong khoảng từ 10 đến 20. Đây thực sự là hai điều kiện: chúng ta cần biết nếu x lớn hơn 10 hay không và x có nhỏ hơn 20 không.
/**
* Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
*
* @author cafedevn
* Contact: cafedevn@gmail.com
* Fanpage: https://www.facebook.com/cafedevn
* Instagram: https://instagram.com/cafedevn
* Twitter: https://twitter.com/CafedeVn
* Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/
#include <iostream>
int main()
{
std::cout << "Enter a number: ";
int value {};
std::cin >> value;
if (value > 10 && value < 20)
std::cout << "Your value is between 10 and 20\n";
else
std::cout << "Your value is not between 10 and 20\n";
return 0;
}
Trong trường hợp này, chúng ta sử dụng toán tử logic AND để kiểm tra xem điều kiện bên trái (giá trị> 10) AND điều kiện bên phải (giá trị <20) đều đúng hay không. Nếu cả hai đều đúng, toán tử logic AND đánh giá là đúng và câu lệnh if thực thi. Nếu cả hai đều không đúng hoặc chỉ có một là đúng, toán tử logic AND sẽ ước lượng thành false và câu lệnh khác thực thi.
Như với logic OR, bạn có thể xâu chuỗi nhiều câu lệnh logic AND:
if (value > 10 && value < 20 && value != 16)
// do something
else
// do something else
Nếu tất cả các điều kiện này là đúng, câu lệnh if sẽ thực thi. Nếu bất kỳ điều kiện nào trong số này là sai, câu lệnh khác sẽ thực thi.
4. Đánh giá ngắn
Để logic AND trả về true, cả hai toán hạng phải đánh giá thành true. Nếu toán hạng thứ nhất ước lượng thành false, logic AND biết nó phải trả về false bất kể toán hạng thứ hai đánh giá là đúng hay sai. Trong trường hợp này, toán tử logic AND sẽ tiếp tục và trả về false ngay lập tức mà không cần đánh giá toán hạng thứ hai! Điều này được gọi là đánh giá ngắn, và nó được thực hiện chủ yếu cho mục đích tối ưu hóa.
Tương tự, nếu toán hạng đầu tiên cho logic OR là đúng, thì toàn bộ điều kiện OR phải được đánh giá là đúng và toán hạng thứ hai đã thắng được đánh giá.
Đánh giá ngắn thể hiện một cơ hội khác để chỉ ra lý do tại sao các toán tử gây ra tác dụng phụ không nên được sử dụng trong các biểu thức ghép. Hãy xem xét đoạn trích sau:
if (x == 1 && ++y == 2)
// do something
nếu x không bằng 1, toàn bộ điều kiện phải là sai, vì vậy ++ y không bao giờ được đánh giá! Do đó, y sẽ chỉ được tăng lên nếu x ước lượng thành 1, đây có lẽ không phải là điều mà lập trình viên dự định!
Đánh giá ngắn có thể gây ra logic OR và logic AND không đánh giá một toán hạng. Tránh sử dụng các biểu thức có tác dụng phụ kết hợp với các toán tử này.
Như với logic và bitwise OR, đôi khi các lập trình viên mới nhầm lẫn toán tử logic AND (&&) với toán tử bitwise AND (&).
5. Dùng ANDs với ORs
Việc trộn lẫn các toán tử OR và logic OR trong cùng một biểu thức thường không thể tránh được, nhưng đó là một khu vực chứa đầy những nguy hiểm tiềm tàng.
Nhiều lập trình viên cho rằng logic AND và logic OR có cùng mức ưu tiên (hoặc quên rằng họ không có giá trị), giống như phép cộng / phép trừ và phép nhân / phép chia. Tuy nhiên, logic AND có độ ưu tiên cao hơn logic OR, do đó các toán tử logic AND sẽ được đánh giá trước các toán tử logic OR (trừ khi chúng được ngoặc đơn).
Các lập trình viên mới thường sẽ viết các biểu thức như value1 || value2 && value3. Vì logic AND có độ ưu tiên cao hơn, nên giá trị này là value1 | | (value2 && value3), không (value1 || value2) && value3. Hy vọng rằng, những gì các lập trình viên muốn! Nếu lập trình viên giả định đánh giá từ trái sang phải (như xảy ra với phép cộng / phép trừ hoặc phép nhân / phép chia), lập trình viên sẽ nhận được kết quả mà họ không mong đợi!
Khi trộn logic AND và logic OR trong cùng một biểu thức, một ý tưởng tốt là nên ngoặc đơn rõ ràng từng toán tử và toán hạng của nó. Điều này giúp ngăn ngừa các lỗi ưu tiên, làm cho code của bạn dễ đọc hơn và xác định rõ ràng cách bạn dự định biểu thức để đánh giá. Ví dụ: thay vì viết value1 && value2 || value3 && value4, tốt hơn là viết (value1 && value2) || (value3 && value4).
6. Luật De Morgan’s
Nhiều lập trình viên cũng mắc sai lầm khi nghĩ rằng! (X && y) giống với! X &&! Y. Thật không may, bạn không thể phân phối các kênh logic NOT theo cách đó.
Luật De Morgan, cho chúng ta biết cách phân phối logic NOT trong các trường hợp sau:
!(x && y) is equivalent to !x || !y
!(x || y) is equivalent to !x && !y
Nói cách khác, khi bạn phân phối logic NOT, bạn cũng cần phải lật logic AND sang logic OR ngược lại!
Điều này đôi khi có thể hữu ích khi cố gắng làm cho các biểu thức phức tạp dễ đọc hơn.
7. Toán tử (XOR)
Logical XOR là một toán tử logic được cung cấp trong một số ngôn ngữ được sử dụng để kiểm tra xem một số điều kiện lẻ có đúng hay không.
Logical XOR | ||
---|---|---|
Toán hạng bên trái | Toán hạng bên phải | Kết quả |
false | false | false |
false | true | true |
true | false | true |
true | true | false |
C ++ không cung cấp một toán tử logic XOR. Không giống như logic OR hoặc logic AND, logic XOR không thể được đánh giá ngắn. Bởi vì điều này, làm cho một toán tử logic XOR ra khỏi các toán tử OR và logic AND là một thách thức. Tuy nhiên, bạn có thể dễ dàng bắt chước logic XOR bằng toán tử bất đẳng thức (! =):
if (a != b) ... // a XOR b, assuming a and b are Booleans
Điều này có thể được mở rộng cho nhiều toán hạng như sau:
if (a != b != c != d) ... // a XOR b XOR c XOR d, assuming a, b, c, and d are Booleans
Lưu ý rằng các mẫu XOR ở trên chỉ hoạt động nếu toán hạng là Booleans (không phải số nguyên). Nếu bạn cần một dạng XOR logic hoạt động với các toán hạng không phải Boolean, bạn có thể static_cast chúng để bool:
if (static_cast<bool>(a) != static_cast<bool>(b) != static_cast<bool>(c) != static_cast<bool>(d)) ... // a XOR b XOR c XOR d, for any type that can be converted to bool