Câu lệnh lặp


Trong lập trình, ta thường xuyên phải thực hiện các thao tác lặp đi lặp lại nhiều lần: In ra các số tự nhiên liên tiếp, in ra nhiều kí tự, ...

Ví dụ

Viết chương trình in ra các số tự nhiên liên tiếp từ \(1\) đến \(10\).

Mã nguồn

C++
#include <bits/stdc++.h>

using namespace std;

int main() {
    cout << 1 << " ";
    cout << 2 << " ";
    cout << 3 << " ";
    cout << 4 << " ";
    cout << 5 << " ";
    cout << 6 << " ";
    cout << 7 << " ";
    cout << 8 << " ";
    cout << 9 << " ";
    cout << 10 << " ";

    return 0;
}

Đầu ra

1 2 3 4 5 6 7 8 9 10

Có thể thấy, cách làm "thủ công" như trên yêu cầu viết đi viết lại một câu lệnh nhiều lần. Đây là một cách làm kém hiệu quả, gây tốn thời gian và dễ xảy ra sai sót khi cần chỉnh sửa.

Để giải quyết vấn đề này, C++ cung cấp một giải pháp hiệu quả: các câu lệnh lặp. Các câu lệnh lặp này tự động hóa hoàn toàn các tác vụ lặp lại, giúp cho chương trình đơn giản và gọn gàng hơn.


Câu lệnh lặp for

Cú pháp:

C++
for (<khởi_tạo>; <điều_kiện>; <cập_nhật>) {
    // Các câu lệnh được thực thi mỗi lần lặp
}

Để hiểu rõ hơn về cơ chế thực hiện câu lệnh lặp for, ta xét ví dụ sau:

Ví dụ 1

Mã nguồn

C++
for (int i = 1; i <= 5; i++) {
    cout << i << " ";
}

Đầu ra

1 2 3 4 5 

Một vòng lặp sẽ thực hiện các bước lần lượt sau:

  • Bước 1: Thực hiện khởi tạo \textbf{biến lặp} i = 1.
  • Bước 2: Thực hiện kiểm tra điều kiện i <= 5:
    • Nếu điều kiện trả về false thì dừng vòng lặp.
    • Nếu điều kiện trả về true thì tiếp tục Bước 3.
  • Bước 3: Thực hiện các lệnh trong khối lệnh đặt trong cặp ngoặc nhọn.
  • Bước 4: Thực hiện việc cập nhật biến lặp i++ và quay lại \textbf{Bước 2}.
    \end{itemize}

!!! primary "Ví dụ 2
Cho hai số nguyên a} #!cpp b}. In ra các số chẵn từ a} đến#!cpp b}.
!!! primary "Mã nguồn"

C++
int main() {
    int a, b;
    cin >> a >> b;

    for (int i = a; i <= b; i++) {
        if (i % 2 == 0) {
            cout << i << " ";
        }
    }

    return 0;
}

!!! primary "Đầu vào"
    ```sample
    5 20
    ```
!!! primary "Đầu ra"
    ```sample
    6 8 10 12 14 16 18 20
    ```

Ví dụ 3

Cho số nguyên dương \(n\). Đếm số lượng các số lẻ từ 1 đến n.

Mã nguồn

C++
int main() {
    int n;
    cin >> n;

    int dem_le = 0;
    for (int i = a; i <= b; i++) {
        if (i % 2 == 1) {
            dem_le++;
        }
    }

    cout << dem_le;

    return 0;
}

Đầu vào

10

Đầu ra

5

Ở ví dụ trên, ta sử dụng biến dem_le để lưu số lượng số lẻ. Tương tự như vậy, ta cũng sử dụng biến phụ để đếm số lượng, tính tổng các số, tính tích các số,\ldots trong một khoảng giá trị.

Câu lệnh lặp while

Cú pháp:

C++
while (<điều_kiện>) {
    // Khối lệnh được thực thi mỗi lần lặp
}

Ví dụ 1

Tính tổng các số tự nhiên chia hết cho \(3\) nhỏ hơn \(20\).

Mã nguồn

C++
int main() {  
    int i = 3, tong = 0;
    while (i < 20) {
        tong += i;
        i += 3;
    }
    cout << tong;
    return 0;
}

Đầu ra

C++
63

Vòng lặp while trên sẽ thực hiện kiểm tra điều kiện i < 20:

  • Nếu điều kiện i < 20 trả về true, các lệnh bên trong khối lệnh sẽ được thực hiện. Sau đó, việc kiểm tra điều kiện lặp lại.
  • Nếu điều kiện i < 20 trả về false, vòng lặp while kết thúc.

Trong đoạn chương trình trên, lệnh lặp sẽ dừng khi \(i \geq 20\), và giá trị tong là 63.

Ví dụ 2

Tăng dần giá trị k cho đến khi bình phương của k lớn hơn \(1000\).

Mã nguồn

C++
int main() { 
    int k = 0;
    while (k * k <= 1000) {
        k++;
    }
    cout << k << " " << k * k;
    return 0;
}

Đầu ra

32 1024

Ở ví dụ trên, biến k được tăng dần từ \(0, 1, 2, \ldots\) cho đến \(32\). Khi k = 32, điều kiện k * k <= 1000 trả về false, vòng lặp dừng lại.

Ví dụ 3

Giảm dần số a một đơn vị cho đến khi a chia hết cho b:

Mã nguồn

C++
int main() {
    int a = 13, b = 5;
    while (a % b != 0) {
        a--;
    }
    cout << a;
    return 0;
}

Đầu ra

10

Nhận xét: Câu lệnh lặp for thường được sử dụng khi điều kiện lặp đơn giản và số lần lặp có thể được xác định trước: từ 1 đến n, từ a đến b, ... Câu lệnh lặp while thường được sử dụng với các vòng lặp có điều kiện khó xác định trước số lần lặp: k * k <= 1000, a % b != 0, ...

Các câu lệnh can thiệp vòng lặp phổ biến

Câu lệnh break

Câu lệnh break khi thực thi sẽ dừng vòng lặp đang chạy ngay lập tức.

Ví dụ

Mã nguồn

C++
int main() {
    for (int i = 1; i <= 10; i++) { 
        if (i == 6) {
            break;
        }
        cout << i << " ";
    }
    return 0;
}

Đầu ra

1 2 3 4 5

Ở ví dụ trên, khi biến i đạt giá trị \(6\), vòng lặp bị dừng bởi câu lệnh break. Do đó, câu lệnh cout << i << " " với i = 6, 7, 8, 9, 10 không được thực thi.

Câu lệnh break cũng có thể được kết hợp với vòng lặp while:

Ví dụ

Mã nguồn

C++
int main() {
    int i = 1;
    while (i <= 10) {
        if (i % 5 == 0) {
            break;
        } 
        cout << i << " ";
        i++;
    }

    return 0;
}

Đầu ra

1 2 3 4

Câu lệnh continue

Câu lệnh continue khi thực thi sẽ \textbf{bỏ qua các câu lệnh bên dưới của lần lặp hiện tại}, và tiếp tục lần lặp tiếp theo.

Ví dụ 1

Mã nguồn

C++
int main() {
    for (int i = 1; i <= 10; i++) {
        if (i % 3 == 0) {
            continue;
        }
        cout << i << " ";
    }

    return 0;
}

Đầu ra

1 2 4 5 7 8 10

Khi điều kiện i % 3 == 0 thỏa mãn, câu lệnh continue được thực hiện, bỏ qua câu lệnh cout khi biến i = 3, 6, 9.

Ví dụ 2

Mã nguồn

C++
int main() {
    for (int i = 1; i <= 10; i++) {
        if (i < 5) {
            continue;
        }
        cout << i << " ";
    }

    return 0;
}

Đầu ra

C++
5 6 7 8 9 10

Vòng lặp lồng nhau

Một vòng lặp có thể đặt lồng bên trong một vòng lặp khác.

Ví dụ 1

Nhập một số nguyên dương \(n\) từ bàn phím. In ra hình vuông gồm các dấu * có độ dài cạnh bằng \(n\).

Mã nguồn

C++
int main() {
    int n;
    cin >> n;

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cout << "*";
        }
        cout << "\n";
    }

    return 0;
}

Đầu vào

4

Đầu ra

****
****
****
****

Ví dụ 2

Nhập một số nguyên dương \(n\) từ bàn phím. In ra hình tam giác vuông cân có cạnh góc vuông độ dài \(n\) sử dụng các dấu *.

Mã nguồn

C++
int main() {
    int n;
    cin >> n;

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= i; j++) {
            cout << "*";
        }
        cout << "\n";
    }

    return 0;
}

Đầu vào

5

Đầu ra

*
**
***
****
*****