Thứ tự ưu tiên toán tử gây nhầm lẫn
Vấn đề
Phần tiêu đề “Vấn đề”C++ có hơn 30 toán tử với thứ tự ưu tiên phức tạp - một số kết hợp rất dễ gây ra kết quả không như mong đợi, dù code vẫn biên dịch bình thường.
Cạm bẫy 1: <</>> với toán tử số học
Phần tiêu đề “Cạm bẫy 1: <</>> với toán tử số học”#include <iostream>
int main() { int a = 5, b = 3; std::cout << a + b << std::endl; // OK - in ra 8, vì + có độ ưu tiên cao hơn <<
// std::cout << "Tong: " << a + b > 5 << std::endl; // Cực kỳ dễ nhầm - > có độ ưu tiên THẤP hơn <<! // Được hiểu là: (std::cout << "Tong: " << a + b) > (5 << std::endl) - LỖI BIÊN DỊCH khó hiểu
std::cout << "Tong: " << (a + b > 5) << std::endl; // Phải thêm ngoặc để rõ ràng
return 0;}Cạm bẫy 2: Bitwise vs Logical
Phần tiêu đề “Cạm bẫy 2: Bitwise vs Logical”int a = 5, b = 3;
// & có độ ưu tiên THẤP HƠN == - dễ gây lỗi nếu quên ngoặcif (a & b == 1) { // Được hiểu là: a & (b == 1), KHÔNG PHẢI (a & b) == 1 !! std::cout << "Ket qua khong nhu mong doi" << std::endl;}
if ((a & b) == 1) { // Đúng ý muốn - luôn thêm ngoặc khi trộn bitwise và so sánh std::cout << "Dung logic mong muon" << std::endl;}Cạm bẫy 3: Toán tử ba ngôi lồng nhau
Phần tiêu đề “Cạm bẫy 3: Toán tử ba ngôi lồng nhau”int score = 75;
// Khó đọc, dễ hiểu sai khi lồng nhiều toán tử ba ngôistd::string grade = score >= 90 ? "A" : score >= 80 ? "B" : score >= 70 ? "C" : "F";
// Rõ ràng hơn với ngoặc, dù dài hơnstd::string grade2 = (score >= 90) ? "A" : ((score >= 80) ? "B" : ((score >= 70) ? "C" : "F"));
// Rõ ràng nhất: dùng if/else thông thường khi logic phức tạpstd::string grade3;if (score >= 90) grade3 = "A";else if (score >= 80) grade3 = "B";else if (score >= 70) grade3 = "C";else grade3 = "F";Cạm bẫy 4: Gán (=) vs so sánh (==) trong điều kiện
Phần tiêu đề “Cạm bẫy 4: Gán (=) vs so sánh (==) trong điều kiện”int x = 5;
if (x = 10) { // LỖI LOGIC (nhưng vẫn biên dịch được)! Đây là GÁN, không phải so sánh std::cout << "Luon vao day, vi x = 10 la gia tri khac 0 (true)" << std::endl;}std::cout << x << std::endl; // 10 - x đã bị thay đổi ngoài ý muốn!
if (x == 10) { // ĐÚNG - toán tử so sánh std::cout << "So sanh dung" << std::endl;}Nhiều trình biên dịch cảnh báo về trường hợp này (-Wall sẽ cảnh báo “using the result of an assignment as a condition”) - luôn chú ý đến các cảnh báo này.
Giải pháp chung
Phần tiêu đề “Giải pháp chung”- Luôn dùng ngoặc
()khi kết hợp nhiều loại toán tử khác nhau, ngay cả khi bạn nhớ đúng thứ tự ưu tiên - code sẽ dễ đọc hơn cho người khác (và cho chính bạn sau này) - Bật cảnh báo trình biên dịch tối đa (
-Wall -Wextra) để bắt các lỗi gõ nhầm=/== - Tránh lồng nhiều toán tử ba ngôi - ưu tiên
if/elsekhi logic phức tạp hơn một cấp
Tóm tắt
Phần tiêu đề “Tóm tắt”Thứ tự ưu tiên toán tử trong C++ khá phức tạp, đặc biệt khi trộn
<</>>, bitwise, và toán tử so sánh.
- Luôn dùng ngoặc để làm rõ ý định, đừng dựa vào việc nhớ chính xác bảng độ ưu tiên
- Cẩn thận gõ nhầm
=thay vì==trong điều kiện - đây là lỗi cú pháp hợp lệ nhưng sai logic