Thứ Tự Ưu Tiên Toán Tử Trong C: Hiểu Đúng Để Lập Trình Chính Xác

1. Giới thiệu

Thứ tự ưu tiên của các toán tử trong ngôn ngữ C rất quan trọng để hiểu đúng cách hoạt động của chương trình và đảm bảo kết quả như mong muốn. Đặc biệt, nếu hiểu sai thứ tự đánh giá toán tử, bạn có thể gặp phải kết quả không như ý hoặc lỗi chương trình. Trong bài viết này, chúng tôi sẽ giải thích chi tiết về thứ tự ưu tiên và quy tắc kết hợp của các toán tử chính trong C, đồng thời đưa ra ví dụ minh họa cụ thể giúp bạn hiểu sâu hơn.

2. Các loại toán tử và cách sử dụng cơ bản

2.1 Toán tử số học

Toán tử số học là các toán tử cơ bản dùng để tính toán với số. Chúng được sử dụng thường xuyên trong lập trình, vì vậy cần nắm vững kiến thức cơ bản về chúng.

  • + (Cộng): Cộng hai số.
  • - (Trừ): Trừ hai số.
  • * (Nhân): Nhân hai số.
  • / (Chia): Chia hai số (khi chia số nguyên, phần thập phân bị loại bỏ).
  • % (Chia lấy dư): Lấy phần dư khi chia hai số nguyên.

Ví dụ:

int a = 10, b = 3;
int sum = a + b;  // 13
int diff = a - b; // 7
int prod = a * b; // 30
int quot = a / b; // 3
int rem = a % b;  // 1

2.2 Toán tử so sánh

Toán tử so sánh dùng để so sánh hai giá trị, kết quả trả về là đúng (1) hoặc sai (0). Chúng thường được sử dụng trong các câu lệnh điều kiện hoặc vòng lặp.

  • > (Lớn hơn): Đúng nếu giá trị bên trái lớn hơn bên phải.
  • < (Nhỏ hơn): Đúng nếu giá trị bên trái nhỏ hơn bên phải.
  • >= (Lớn hơn hoặc bằng): Đúng nếu giá trị bên trái lớn hơn hoặc bằng bên phải.
  • <= (Nhỏ hơn hoặc bằng): Đúng nếu giá trị bên trái nhỏ hơn hoặc bằng bên phải.
  • == (Bằng nhau): Đúng nếu hai giá trị bằng nhau.
  • != (Không bằng): Đúng nếu hai giá trị khác nhau.
int a = 5, b = 10;
if (a < b) {
    printf("a nhỏ hơn b
");  // Được in ra màn hình
}

 

3. Thứ tự ưu tiên và quy tắc kết hợp của toán tử

3.1 Thứ tự ưu tiên của toán tử

Thứ tự ưu tiên của toán tử quyết định toán tử nào được đánh giá trước trong một biểu thức có nhiều toán tử. Dưới đây là một phần bảng thứ tự ưu tiên toán tử trong C, sắp xếp từ cao xuống thấp.

Thứ tự ưu tiênToán tửGiải thích
1() [] -> .Gọi hàm, truy cập mảng, thành viên con trỏ
2++ --Tăng/giảm hậu tố (postfix)
3++ --Tăng/giảm tiền tố (prefix), toán tử dấu
4* / %Nhân, chia, chia lấy dư
5+ -Cộng, trừ
6<< >>Dịch bit
7< <= > >=Toán tử so sánh
8== !=Bằng, không bằng
9&Phép AND bit
10^Phép XOR bit
11|Phép OR bit
12&&Phép AND logic
13||Phép OR logic
14? :Toán tử điều kiện
15= += -=Gán, gán kết hợp
16,Toán tử phẩy

3.2 Quy tắc kết hợp

Quy tắc kết hợp xác định hướng đánh giá khi có nhiều toán tử cùng mức ưu tiên. Hầu hết các toán tử trong C kết hợp từ trái sang phải (trái kết hợp), nhưng một số (như toán tử gán, toán tử điều kiện) lại kết hợp từ phải sang trái (phải kết hợp).

  • Trái kết hợp: Các toán tử như *, +, - được đánh giá từ trái sang phải.
  • Phải kết hợp: Các toán tử gán hoặc toán tử điều kiện ? : được đánh giá từ phải sang trái.
int a = 5, b = 10, c = 15;
int result = a - b + c;  // Trái kết hợp (a - b) + c = 0

4. Lưu ý về thứ tự ưu tiên của một số toán tử

4.1 Toán tử logic

Toán tử AND logic (&&) và OR logic (||) được dùng để kết hợp các điều kiện, trong đó && có ưu tiên cao hơn ||. Do đó, cần chú ý trong các trường hợp như sau:

int a = 1, b = 0, c = 1;
if (a && b || c) {
    printf("Truen");  // Được in ra màn hình
}

Trong ví dụ này, a && b được đánh giá trước rồi mới đến || c. Để đảm bảo thứ tự đúng, nên dùng dấu ngoặc để chỉ rõ ý định.

if ((a && b) || c) {
    // Đánh giá rõ ràng hơn
}

4.2 Toán tử bit

Các toán tử bit (&, |, ^) thao tác trên từng bit nhưng có thứ tự ưu tiên thấp hơn so với toán tử số học hoặc so sánh, do đó cần chú ý khi viết biểu thức phức tạp.

int x = 5;  // 0101
int y = 3;  // 0011
int result = x & y;  // 0001 (AND bit)

5. Ví dụ chương trình thực tế

Dưới đây là ví dụ về chương trình dễ bị hiểu nhầm thứ tự ưu tiên của toán tử. Nhiều người thường nhầm lẫn khi dùng ||&& cùng lúc.

#include <stdio.h>
int main() {
    int a = 0, b = 1;
    if (a == 0 || a == 1 && b == 0) {
        printf("Truen");  // Được in ra màn hình
    }
    return 0;
}

Trong ví dụ này, a == 1 && b == 0 được đánh giá trước, có thể dẫn đến kết quả không như mong muốn. Để có kết quả đúng, nên sử dụng dấu ngoặc để chỉ rõ thứ tự đánh giá.

if ((a == 0 || a == 1) && b == 0) {
    printf("Truen");
}

6. Kết luận

Thứ tự ưu tiên của toán tử trong ngôn ngữ C là yếu tố thiết yếu để chương trình chạy đúng. Khi làm việc với các biểu thức phức tạp, hãy hiểu rõ về thứ tự ưu tiên và quy tắc kết hợp, đồng thời sử dụng dấu ngoặc hợp lý để tránh lỗi không mong muốn. Chú ý đến thứ tự ưu tiên sẽ giúp bạn lập trình an toàn và hiệu quả hơn.