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
#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:
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
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.
- Nếu điều kiện trả về
- 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} và
#!cpp b}. In ra các số chẵn từ a} đến
#!cpp b}.
!!! primary "Mã nguồn"
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
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:
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
int main() {
int i = 3, tong = 0;
while (i < 20) {
tong += i;
i += 3;
}
cout << tong;
return 0;
}
Đầu ra
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ặpwhile
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
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
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
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
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
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
int main() {
for (int i = 1; i <= 10; i++) {
if (i < 5) {
continue;
}
cout << i << " ";
}
return 0;
}
Đầu ra
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
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
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
*
**
***
****
*****