Bài 2.1: Cấu trúc rẽ nhánh if-else trong C++

Chào mừng bạn trở lại với series bài viết về C++!

Trong cuộc sống, chúng ta luôn đưa ra các quyết định dựa trên những điều kiện nhất định. Nếu trời mưa, thì tôi sẽ mang ô. Nếu không mưa, thì tôi sẽ không mang. Lập trình cũng vậy! Chương trình máy tính không phải lúc nào cũng chạy thẳng một lèo từ đầu đến cuối theo thứ tự từng dòng lệnh. Rất thường xuyên, chúng ta cần chương trình của mình lựa chọn thực hiện khối lệnh này hoặc khối lệnh khác dựa trên một điều kiện nào đó có đúng hay không.

Đây chính là lúc cấu trúc rẽ nhánh phát huy sức mạnh! Và trong C++, cấu trúc rẽ nhánh cơ bản và phổ biến nhất chính là if-else.

1. Tại sao cần rẽ nhánh?

Hãy tưởng tượng bạn viết một chương trình tính tiền giảm giá. Nếu tổng hóa đơn lớn hơn 1.000.000 VNĐ, bạn muốn áp dụng giảm giá 10%. Ngược lại, nếu không đạt mức đó, bạn không giảm giá. Làm sao để code "biết" khi nào cần áp dụng giảm giá?

Hoặc một ví dụ khác: yêu cầu người dùng nhập tuổi. Nếu tuổi nhỏ hơn 18, thông báo họ là trẻ vị thành niên. Nếu tuổi từ 18 trở lên, thông báo họ là người trưởng thành.

Trong cả hai trường hợp này, luồng thực thi của chương trình cần rẽ theo hai hướng khác nhau tùy thuộc vào giá trị của một biến hoặc kết quả của một phép kiểm tra.

2. Cấu trúc if cơ bản

Cấu trúc if (nếu) là dạng rẽ nhánh đơn giản nhất. Nó kiểm tra một điều kiện. Nếu điều kiện đó đúng (true), khối lệnh bên trong if sẽ được thực thi. Nếu điều kiện sai (false), khối lệnh đó sẽ bị bỏ qua hoàn toàn và chương trình tiếp tục chạy từ sau khối if.

Cú pháp:

if (bieu_thuc_dieu_kien) {
    // Khối lệnh sẽ thực thi nếu bieu_thuc_dieu_kien là TRUE
}
// Chương trình tiếp tục chạy từ đây sau khi khối if kết thúc
  • bieu_thuc_dieu_kien: Đây là một biểu thức mà kết quả của nó phải là giá trị logic (true hoặc false). Thường là các phép so sánh (>, <, ==, !=, >=, <=) hoặc các phép kết hợp logic (&&, ||, !). Trong C++, giá trị khác 0 được coi là true, 0 được coi là false. Tuy nhiên, luôn nên sử dụng các biểu thức trả về bool rõ ràng cho điều kiện để code dễ đọc và tránh lỗi.
  • { ... }: Dấu ngoặc nhọn bao quanh khối lệnh sẽ được thực thi. Nếu chỉ có một dòng lệnh duy nhất bên trong if, bạn có thể bỏ qua dấu ngoặc nhọn, nhưng khuyến khích luôn sử dụng dấu ngoặc nhọn để code rõ ràng hơn và tránh sai sót khi thêm dòng lệnh sau này.

Ví dụ 1: Kiểm tra số dương

#include <iostream>

int main() {
    int number;
    cout << "Nhap mot so nguyen: ";
    cin >> number;

    // Kiem tra xem so co lon hon 0 khong
    if (number > 0) {
        cout << "Day la mot so duong." << endl;
    }

    cout << "Ket thuc chuong trinh." << endl; // Dong nay luon chay

    return 0;
}
  • Giải thích:
    • Chương trình yêu cầu người dùng nhập một số.
    • Dòng if (number > 0) kiểm tra điều kiện: biến number có lớn hơn 0 không?
    • Nếu người dùng nhập 5 (5 > 0true), dòng "Day la mot so duong." sẽ được in ra. Sau đó, "Ket thuc chuong trinh." cũng in ra.
    • Nếu người dùng nhập -3 (-3 > 0false), dòng "Day la mot so duong." sẽ bị bỏ qua. Chương trình nhảy thẳng đến dòng "Ket thuc chuong trinh." và in nó ra.
    • Nếu người dùng nhập 0 (0 > 0false), dòng "Day la mot so duong." cũng bị bỏ qua.

3. Cấu trúc if-else

Cấu trúc if-else (nếu-thì khác) cho phép bạn chỉ định hai khối lệnh đối lập nhau: một khối thực thi khi điều kiện đúng và một khối thực thi khi điều kiện sai.

Cú pháp:

if (bieu_thuc_dieu_kien) {
    // Khối lệnh 1: Thực thi nếu bieu_thuc_dieu_kien là TRUE
} else {
    // Khối lệnh 2: Thực thi nếu bieu_thuc_dieu_kien là FALSE
}
// Chương trình tiếp tục chạy từ đây sau khi khối if-else kết thúc
  • Chỉ một trong hai khối lệnh (hoặc trong if, hoặc trong else) sẽ được thực thi, không bao giờ cả hai, và cũng không bao giờ không có khối nào được thực thi (trừ khi có lệnh nhảy như return, break, continue bên trong).

Ví dụ 2: Kiểm tra số chẵn/lẻ

#include <iostream>

int main() {
    int number;
    cout << "Nhap mot so nguyen: ";
    cin >> number;

    // Kiem tra xem so la chan hay le
    if (number % 2 == 0) { // Toan tu % la phep chia lay du
        cout << number << " la so chan." << endl;
    } else {
        cout << number << " la so le." << endl;
    }

    cout << "Hoan thanh kiem tra." << endl; // Dong nay luon chay

    return 0;
}
  • Giải thích:
    • Chương trình đọc một số nguyên.
    • number % 2 == 0: Điều kiện kiểm tra số dư của number khi chia cho 2 có bằng 0 không. Nếu bằng 0 (ví dụ: 4 % 2 == 0), số đó là chẵn. Nếu không bằng 0 (ví dụ: 5 % 2 == 1), số đó là lẻ.
    • Nếu điều kiện number % 2 == 0true, khối lệnh trong if (cout << number << " la so chan." << endl;) sẽ chạy.
    • Nếu điều kiện là false, khối lệnh trong else (cout << number << " la so le." << endl;) sẽ chạy.
    • Dòng "Hoan thanh kiem tra." luôn chạy sau khi cấu trúc if-else hoàn thành.

4. Cấu trúc if-else if-else (Xử lý nhiều điều kiện)

Thường thì chúng ta cần kiểm tra nhiều hơn hai khả năng. Ví dụ: điểm số có thể là A, B, C, D, hoặc F. Lúc này, cấu trúc if-else if-else rất hữu ích. Nó cho phép bạn kiểm tra một loạt các điều kiện theo thứ tự.

Cú pháp:

if (bieu_thuc_dieu_kien_1) {
    // Khối lệnh 1: Thực thi nếu bieu_thuc_dieu_kien_1 là TRUE
} else if (bieu_thuc_dieu_kien_2) {
    // Khối lệnh 2: Thực thi nếu bieu_thuc_dieu_kien_1 là FALSE VÀ bieu_thuc_dieu_kien_2 là TRUE
} else if (bieu_thuc_dieu_kien_3) {
    // Khối lệnh 3: Thực thi nếu dieu_kien_1 FALSE, dieu_kien_2 FALSE VÀ bieu_thuc_dieu_kien_3 là TRUE
}
// ... Có thể có nhiều else if nữa ...
else {
    // Khối lệnh N: Thực thi nếu TẤT CẢ các dieu_kien_tren đều là FALSE
}
// Chương trình tiếp tục chạy từ đây
  • Các điều kiện được kiểm tra từ trên xuống dưới.
  • Ngay khi một điều kiện đúng được tìm thấy, khối lệnh tương ứng với điều kiện đó sẽ được thực thi, và toàn bộ cấu trúc if-else if-else sẽ kết thúc (các else if hoặc else còn lại sẽ bị bỏ qua).
  • Khối else cuối cùng (nếu có) sẽ chỉ được thực thi khi tất cả các điều kiện ifelse if trước đó đều sai. Khối else này là tùy chọn.

Ví dụ 3: Xếp loại học lực

#include <iostream>

int main() {
    double score;
    cout << "Nhap diem so (0-10): ";
    cin >> score;

    // Xep loai hoc luc dua tren diem
    if (score >= 9.0) {
        cout << "Xep loai: Xuat sac" << endl;
    } else if (score >= 8.0) {
        cout << "Xep loai: Gioi" << endl;
    } else if (score >= 7.0) {
        cout << "Xep loai: Kha" << endl;
    } else if (score >= 5.0) {
        cout << "Xep loai: Trung binh" << endl;
    } else { // Diem duoi 5.0
        cout << "Xep loai: Yeu" << endl;
    }

    return 0;
}
  • Giải thích:
    • Chương trình đọc điểm số.
    • Kiểm tra từ trên xuống:
      • Nếu score >= 9.0 (ví dụ: 9.5), in "Xuat sac" và dừng.
      • Ngược lại, nếu score >= 8.0 (ví dụ: 8.2, điều kiện đầu tiên false), in "Gioi" và dừng.
      • Ngược lại, nếu score >= 7.0 (ví dụ: 7.0), in "Kha" và dừng.
      • Ngược lại, nếu score >= 5.0 (ví dụ: 6.5), in "Trung binh" và dừng.
      • Nếu tất cả các điều kiện trên đều sai (ví dụ: 4.9), in "Yeu".
    • Thứ tự các else if rất quan trọng trong trường hợp này! Nếu bạn kiểm tra score >= 5.0 trước score >= 9.0, một điểm 9.5 sẽ rơi vào trường hợp "Trung binh" (vì 9.5 >= 5.0 là true) và các điều kiện sau sẽ không bao giờ được kiểm tra.

5. Cấu trúc if lồng nhau (Nested if)

Bạn có thể đặt một cấu trúc if, if-else, hoặc if-else if bên trong một khối lệnh của một cấu trúc if hoặc else khác. Điều này được gọi là if lồng nhau.

Cú pháp:

if (dieu_kien_ngoai) {
    // Khối lệnh chỉ chạy nếu dieu_kien_ngoai TRUE
    if (dieu_kien_ben_trong_1) {
        // Khối lệnh chỉ chạy nếu dieu_kien_ngoai TRUE VÀ dieu_kien_ben_trong_1 TRUE
    } else {
        // Khối lệnh chỉ chạy nếu dieu_kien_ngoai TRUE VÀ dieu_kien_ben_trong_1 FALSE
    }
} else {
    // Khối lệnh chỉ chạy nếu dieu_kien_ngoai FALSE
}
  • Điều kiện bên trong chỉ được kiểm tra nếu điều kiện bên ngoài là đúng.

Ví dụ 4: Kiểm tra tuổi và quyền truy cập

#include <iostream>
#include <string>

int main() {
    int age;
    char hasPermission; // 'Y' hoac 'N'

    cout << "Nhap tuoi cua ban: ";
    cin >> age;

    // Kiem tra tuoi
    if (age >= 18) {
        cout << "Ban la nguoi truong thanh." << endl;

        // Neu da truong thanh, tiep tuc kiem tra quyen
        cout << "Ban co quyen truy cap (Y/N)? ";
        cin >> hasPermission;

        if (hasPermission == 'Y' || hasPermission == 'y') {
            cout << "Duoc phep truy cap hoan toan." << endl;
        } else {
            cout << "Khong duoc phep truy cap day du (mac du da truong thanh)." << endl;
        }

    } else { // age < 18
        cout << "Ban la tre vi thanh nien." << endl;
        cout << "Khong duoc phep truy cap." << endl;
    }

    return 0;
}
  • Giải thích:
    • Chương trình đầu tiên kiểm tra age >= 18.
    • Nếu đúng, nó in thông báo "truong thanh" và sau đó mới tiến hành hỏi về quyền truy cập và kiểm tra điều kiện lồng nhau hasPermission == 'Y' || hasPermission == 'y'.
    • Nếu age >= 18sai (tức là tuổi < 18), khối else ngoài cùng sẽ chạy, in thông báo "tre vi thanh nien" và "khong duoc phep truy cap", bỏ qua hoàn toàn phần kiểm tra quyền bên trong khối if đầu tiên.

Cấu trúc lồng nhau cho phép bạn xây dựng các logic điều khiển phức tạp hơn. Tuy nhiên, lồng quá sâu có thể làm code khó đọc, nên hãy sử dụng một cách hợp lý.

6. Biểu thức điều kiện chi tiết hơn

Như đã đề cập, biểu thức điều kiện trong if, else if là những biểu thức trả về giá trị logic (true hoặc false). Các toán tử thường dùng để tạo biểu thức này bao gồm:

  • Toán tử so sánh:

    • == (bằng)
    • != (khác)
    • > (lớn hơn)
    • < (nhỏ hơn)
    • >= (lớn hơn hoặc bằng)
    • <= (nhỏ hơn hoặc bằng)
    • Ví dụ: score >= 5.0, age == 18, name != "Admin".
  • Toán tử logic: Dùng để kết hợp nhiều điều kiện nhỏ.

    • && (AND logic): Trả về true nếu cả hai điều kiện con đều true.
    • || (OR logic): Trả về true nếu ít nhất một điều kiện con là true.
    • ! (NOT logic): Đảo ngược giá trị logic (true thành false, false thành true).
    • Ví dụ:
      • age >= 18 && hasPermission == 'Y' (Trưởng thành có quyền).
      • score >= 8.0 || attendance > 90 (Điểm giỏi hoặc chuyên cần cao).
      • !(isBlocked) (Không bị chặn).

Ví dụ 5: Sử dụng toán tử logic

#include <iostream>
#include <string>

int main() {
    int hour;
    bool isWeekend; // true neu la cuoi tuan, false neu la ngay thuong

    cout << "Nhap gio hien tai (0-23): ";
    cin >> hour;

    char inputWeekend;
    cout << "Hom nay la cuoi tuan (Y/N)? ";
    cin >> inputWeekend;
    isWeekend = (inputWeekend == 'Y' || inputWeekend == 'y'); // Chuyen doi input sang bool

    // Kiem tra xem cua hang co mo cua khong
    // Cua hang mo cua vao ngay thuong tu 8h den 17h, cuoi tuan tu 10h den 15h
    if ((!isWeekend && hour >= 8 && hour <= 17) || (isWeekend && hour >= 10 && hour <= 15)) {
        cout << "Cua hang dang mo cua." << endl;
    } else {
        cout << "Cua hang dang dong cua." << endl;
    }

    return 0;
}
  • Giải thích:
    • Điều kiện chính: (dieu_kien_ngay_thuong_mo_cua) || (dieu_kien_cuoi_tuan_mo_cua).
    • dieu_kien_ngay_thuong_mo_cua: !isWeekend && hour >= 8 && hour <= 17 (Không phải cuối tuần giờ từ 8 đến 17).
    • dieu_kien_cuoi_tuan_mo_cua: isWeekend && hour >= 10 && hour <= 15 (Là cuối tuần giờ từ 10 đến 15).
    • Cửa hàng mở cửa nếu một trong hai điều kiện (ngày thường hoặc cuối tuần) là đúng.

Sử dụng kết hợp các toán tử so sánh và logic cho phép bạn tạo ra các điều kiện phức tạp và chính xác để điều khiển luồng chương trình.

7. Lưu ý khi sử dụng if-else

  • Dấu chấm phẩy ;: Không bao giờ đặt dấu chấm phẩy ngay sau cặp ngoặc đơn () của if hoặc else. Ví dụ: if (condition); { ... } là SAI, nó sẽ làm khối lệnh { ... } luôn được thực thi, độc lập với điều kiện if.
  • Dấu ngoặc nhọn {}: Như đã nói, luôn sử dụng dấu ngoặc nhọn, ngay cả khi chỉ có một dòng lệnh. Điều này giúp code dễ đọc, dễ bảo trì và tránh lỗi khi bạn muốn thêm dòng lệnh vào khối if/else sau này.
  • So sánh bằng ==: Đừng nhầm lẫn toán tử so sánh bằng == với toán tử gán =. if (a = 5) sẽ gán giá trị 5 cho a, và biểu thức này sẽ trả về 5 (được coi là true), làm cho khối if luôn chạy (trừ khi gán giá trị 0). Luôn dùng if (a == 5) để so sánh.
  • Thụt lề (Indentation): Thụt lề code bên trong các khối if, else if, else giúp trực quan hóa cấu trúc rẽ nhánh, làm code dễ đọc hơn rất nhiều. Hãy tuân thủ một quy tắc thụt lề nhất quán.

Tóm lại

Cấu trúc if-else là công cụ không thể thiếu trong bất kỳ ngôn ngữ lập trình nào, giúp chúng ta tạo ra các chương trình có khả năng ra quyết định và điều chỉnh hành vi dựa trên các điều kiện khác nhau.

  • Sử dụng if khi bạn chỉ cần thực hiện một hành động nếu điều kiện đúng.
  • Sử dụng if-else khi bạn cần thực hiện một hành động nếu điều kiện đúng và một hành động khác nếu điều kiện sai.
  • Sử dụng if-else if-else khi bạn cần kiểm tra nhiều điều kiện liên tiếp.
  • Sử dụng if lồng nhau khi điều kiện bên trong phụ thuộc vào kết quả của điều kiện bên ngoài.

Nắm vững cách sử dụng if-else và các biến thể của nó là bước đầu tiên và quan trọng để bạn có thể viết được những chương trình phức tạp và linh hoạt hơn trong C++.

Bài tập ví dụ: C++ Bài 2.A1: Tính tổng(1)

Viết chương trình để tính tổng của hai giá trị nguyên \(x, y\) cho trước. Nếu hai giá trị giống nhau thì trả về gấp ba lần tổng của chúng.

INPUT FORMAT

Dòng đầu tiên chứa giá trị của hai số nguyên \(x, y (1 \leq x, y \leq 10^9)\).

OUTPUT FORMAT

In ra kết quả của chương trình.

Ví dụ 1:

Input
1 2
Ouput
3

Ví dụ 2:

Input
2 2
Output
12
Giải thích ví dụ mẫu
Ví dụ 1

Đầu vào 1 2 dẫn đến tổng là 1 + 2 = 3.

Ví dụ 2

Đầu vào 2 2 dẫn đến tổng là 2 + 2 = 4, và gấp ba lần tổng là 4 * 3 = 12.

<br>

  1. Bao gồm thư viện cần thiết: Bạn cần sử dụng các chức năng nhập và xuất dữ liệu tiêu chuẩn. Hãy include thư viện iostream.
  2. Hàm chính: Viết hàm main(), đây là điểm bắt đầu của chương trình C++.
  3. Khai báo biến:
    • Khai báo hai biến để lưu hai số nguyên đầu vào. Do giá trị có thể lên đến $10^9$, tổng của chúng và gấp ba lần tổng có thể vượt quá giới hạn của kiểu int thông thường trên một số hệ thống (thường là 32-bit). Vì vậy, hãy sử dụng kiểu dữ liệu long long để đảm bảo chứa được các giá trị lớn này.
    • Bạn có thể cần thêm một biến kiểu long long để lưu kết quả cuối cùng.
  4. Đọc dữ liệu: Sử dụng cin để đọc hai số nguyên từ đầu vào và lưu vào hai biến bạn vừa khai báo.
  5. Tính toán tổng: Tính tổng của hai số vừa đọc và lưu vào một biến tạm thời (hoặc có thể tính trực tiếp sau).
  6. Kiểm tra điều kiện:
    • Sử dụng câu lệnh điều kiện if để kiểm tra xem hai số đầu vào có bằng nhau hay không (số_thứ_nhất == số_thứ_hai).
  7. Xử lý theo điều kiện:
    • Nếu hai số bằng nhau: Kết quả cuối cùng sẽ là tổng nhân với 3.
    • Nếu hai số không bằng nhau (sử dụng else): Kết quả cuối cùng chính là tổng của hai số đó.
  8. In kết quả: Sử dụng cout để in giá trị của kết quả cuối cùng ra màn hình. Đừng quên thêm endl hoặc '\n' để xuống dòng sau khi in.
  9. Kết thúc chương trình: Trả về 0 từ hàm main để báo hiệu chương trình chạy thành công.

Làm thêm nhiều bài tập miễn phí tại đây

Comments

There are no comments at the moment.