Menu

if-else trong C++: câu lệnh điều kiện kèm ví dụ

Cách ra quyết định trong C++ với if, else if và else: điều kiện, nối nhiều nhánh, lồng nhau, toán tử ba ngôi, if có khởi tạo, và những cái bẫy hay khiến bạn vấp.

Trang này có trình soạn thảo chạy trực tiếp. Sửa, chạy và xem đầu ra ngay lập tức.

Ra quyết định với if

Chương trình luôn phải phản ứng với dữ liệu: đạt hay trượt, còn hàng hay hết hàng, hợp lệ hay không. Câu lệnh if là cách C++ chọn code nào sẽ chạy dựa trên một điều kiện (condition).

Câu lệnh if nhận một điều kiện trong ngoặc tròn và chỉ chạy khối lệnh trong ngoặc nhọn khi điều kiện đó đúng:

Điều kiện score >= 60 đúng, nên thông báo được in ra. Dòng sau dấu ngoặc nhọn đóng thì luôn chạy, vì nó nằm ngoài if. Đổi score thành 40 và dòng "passed" bị bỏ qua hoàn toàn.

Điều kiện được chuyển thành bool. Các phép so sánh như >, >=, ==, != vốn đã cho ra bool, nhưng C++ còn coi mọi số khác 0 là true và 0 là false, nên if (count) nghĩa là "nếu count khác 0". Phép chuyển đổi ngầm này tiện lợi nhưng cũng là nguồn gốc của vài bug kinh điển mà bạn sẽ thấy bên dưới.

Thêm else

else cho bạn nhánh "ngược lại": code chỉ chạy khi điều kiện sai:

Đúng một trong hai khối sẽ chạy: không bao giờ cả hai, cũng không bao giờ không khối nào. else không có điều kiện riêng; nó đơn giản là đón mọi trường hợp mà if không bắt.

Nối nhánh với else if

Khi có nhiều hơn hai kết quả, hãy nối các điều kiện bằng else if. C++ kiểm tra chúng từ trên xuống dưới và chạy khối đầu tiên có điều kiện đúng, rồi bỏ qua phần còn lại:

Thứ tự rất quan trọng. Vì 84 được so với >= 90 trước (sai), rồi >= 80 (đúng), chương trình dừng ở B và không bao giờ xét các ngưỡng thấp hơn. Đó cũng là lý do bạn không cần viết score >= 80 && score < 90: đã vào được nhánh thứ hai thì chắc chắn score nhỏ hơn 90. Hãy đặt điều kiện hẹp nhất hoặc ưu tiên cao nhất lên đầu.

Lưu ý C++ không có từ khóa elif: else if thực chất là một else mà thân của nó là một if khác. Cách đặt ngoặc chỉ giúp nó trông như một chiếc thang liền mạch.

Bẫy lớn: = và ==

Bug phổ biến nhất với câu lệnh if trong C và C++ là viết = (phép gán) trong khi ý bạn là == (phép so sánh):

x = 5 gán 5 cho x và cả biểu thức có giá trị 5, chuyển thành true, nên nhánh này luôn chạy và bạn đã âm thầm ghi đè x. Code này biên dịch được; hầu hết trình biên dịch chỉ đưa ra cảnh báo. Có hai cách phòng tránh: bật cảnh báo (-Wall) để trình biên dịch báo lỗi này, và cân nhắc đặt hằng số ở vế trước, if (5 == x), vì if (5 = x) là lỗi thật sự mà trình biên dịch bắt được ngay.

Cái bẫy tương tự cũng ẩn trong bool: if (ready = true) biên dịch được và thực hiện phép gán, trong khi if (ready == true) (hoặc chỉ if (ready)) mới là so sánh.

Kết hợp và lồng điều kiện

Kết hợp điều kiện bằng && (và), || (hoặc) và ! (phủ định), hoặc lồng một if vào trong một if khác khi phép kiểm tra sau chỉ có nghĩa khi phép kiểm tra trước đã đúng:

&& và || có cơ chế short-circuit: trong a && b, nếu a sai thì C++ không bao giờ tính b. Điều này rất cần thiết để tránh truy cập bộ nhớ sai: if (ptr != nullptr && ptr->ready) an toàn vì phép dereference con trỏ bị bỏ qua khi ptr là null. Khi có thể, hãy làm phẳng điều kiện bằng && thay vì lồng sâu; một điều kiện phẳng dễ đọc hơn một kim tự tháp ngoặc nhọn.

Cẩn thận với kiểu so sánh nối tiếp không mang ý nghĩa như vẻ ngoài: if (0 < x < 10) không kiểm tra một khoảng. Nó tính 0 < x ra một bool (0 hoặc 1), rồi so giá trị đó với 10, nên luôn đúng. Hãy viết if (0 < x && x < 10).

Toán tử ba ngôi

Khi bạn chỉ muốn chọn giữa hai giá trị, toán tử ba ngôi ?: là cách viết gọn trên một dòng. Đọc condition ? a : b là "nếu condition thì a, ngược lại b":

Toán tử ba ngôi tạo ra một giá trị mà bạn có thể gán, truyền vào hàm hoặc in thẳng ra, điều mà if thông thường không làm được. Hãy dùng nó cho các lựa chọn đơn giản: nếu một nhánh cần nhiều câu lệnh hoặc logic thật sự, if-else đầy đủ vẫn dễ đọc, còn toán tử ba ngôi lồng nhau nhanh chóng biến thành câu đố. (Một chi tiết tinh tế: hai nhánh phải có chung một kiểu, nên đừng trộn, chẳng hạn, một chuỗi với một int.)

if có khởi tạo (C++17)

Từ C++17, bạn có thể khai báo biến ngay bên trong if, với phạm vi chỉ trong if/else. Nhờ vậy các biến tạm sống ngắn không tràn ra code xung quanh:

Phần trước dấu ; chạy một lần và kết quả của nó nhìn thấy được ở cả điều kiện lẫn else. Cách này rất hợp với kiểu "tính một giá trị, rồi rẽ nhánh theo nó", và vì phép tính hay chuyển đổi diễn ra một lần ngay từ đầu, bạn tránh được việc tính lại hoặc vô tình dùng lại một giá trị cũ về sau. Hãy dùng nó bất cứ khi nào một biến tạm chỉ cần cho phép rẽ nhánh.

Một cái bẫy: thiếu dấu ngoặc nhọn

C++ cho phép bỏ ngoặc nhọn khi một nhánh chỉ có một câu lệnh, nhưng điều này dễ dẫn đến một bug tinh vi, vì cách thụt lề đánh lừa bạn:

if (loggedIn)
    cout << "Welcome\n";
    cout << "Loading dashboard\n";   // NOT part of the if!

Chỉ dòng đầu tiên chịu sự điều khiển của if; dòng thứ hai luôn chạy bất kể loggedIn ra sao, dù thụt lề gợi ý điều ngược lại. Một lỗi kinh điển liên quan là dấu chấm phẩy thừa: if (x > 0); kết thúc if với thân rỗng, nên khối lệnh theo sau chạy vô điều kiện. Hãy luôn dùng ngoặc nhọn, kể cả khi chỉ có một dòng, và phần lớn loại lỗi này sẽ biến mất.

Tiếp theo: switch

Chuỗi if-else if rất hợp khi mỗi nhánh kiểm tra một điều kiện khác nhau. Nhưng khi bạn so một giá trị với nhiều khả năng cố định, như một lựa chọn trong menu, một enum hay một mã trạng thái, chiếc thang else if dài sẽ lặp đi lặp lại và dễ bị sắp sai thứ tự. Câu lệnh switch được tạo ra chính cho việc đó, và đó là nội dung của trang tiếp theo.

Câu hỏi thường gặp

Viết câu lệnh if-else trong C++ như thế nào?

Đặt điều kiện trong ngoặc tròn sau if, code cần chạy trong ngoặc nhọn, và thêm khối else (không bắt buộc) cho trường hợp điều kiện sai: if (score >= 60) { cout << "Pass"; } else { cout << "Fail"; }. Điều kiện được chuyển thành bool, nên mọi số khác 0 đều được coi là true và 0 được coi là false.

= và == trong câu lệnh if của C++ khác nhau thế nào?

== so sánh hai giá trị có bằng nhau không, còn một dấu = là phép gán. Viết if (x = 5) sẽ gán 5 cho x rồi kiểm tra 5 (luôn đúng), một bug kinh điển. Code này vẫn biên dịch được và chỉ kèm cảnh báo, nên hãy bật cảnh báo và cân nhắc viết hằng số trước: if (5 == x).

Toán tử ba ngôi trong C++ là gì?

Toán tử ba ngôi condition ? valueIfTrue : valueIfFalse là một dạng if-else gọn, tạo ra một giá trị. Ví dụ string label = age >= 18 ? "adult" : "minor"; chọn một trong hai giá trị. Dùng nó để chọn giá trị đơn giản; khi mỗi nhánh có logic thật sự, hãy dùng if-else đầy đủ.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu