Bỏ qua để đến nội dung

Thứ tự ưu tiên toán tử gây nhầm lẫ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.

#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;
}
int a = 5, b = 3;
// & có độ ưu tiên THẤP HƠN == - dễ gây lỗi nếu quên ngoặc
if (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;
}
int score = 75;
// Khó đọc, dễ hiểu sai khi lồng nhiều toán tử ba ngôi
std::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ơn
std::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ạp
std::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.

  • 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/else khi logic phức tạp hơn một cấp

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