C++ Control Flow

🔁 Vòng lặp for, while và do-while

Vòng lặp giúp chương trình thực hiện một công việc nhiều lần mà không lặp lại code. Bài học trình bày cơ chế từng bước, biến đếm, điều kiện dừng, biến tích lũy, break/continue, vòng lặp lồng nhau và lỗi vòng lặp vô hạn.

forThường dùng khi biết số lần
whileLặp khi điều kiện còn đúng
do-whileChạy ít nhất một lần
O(n)Một lượt qua n phần tử

🎯 Mục tiêu bài học

Cần hiểu

  • Bốn bước: khởi tạo, kiểm tra, thực hiện, cập nhật.
  • Khác nhau giữa for, while, do-while.
  • Biến đếm, biến tích lũy.
  • break, continue.
  • Độ phức tạp vòng lặp.

Cần làm được

  • In dãy theo quy luật.
  • Tính tổng, tích, đếm.
  • Xử lý đến điều kiện dừng.
  • Viết vòng lặp lồng nhau.
  • Phát hiện vòng lặp vô hạn.

1. Đặt vấn đề

Bài toán mở đầu.
Nhập số nguyên dương n. Hãy in các số từ 1 đến n và tính tổng của chúng.

1.1. Nếu không dùng vòng lặp

cout << 1 << ' ';
cout << 2 << ' ';
cout << 3 << ' ';
// Phải viết tiếp đến n

Khi n thay đổi hoặc rất lớn, không thể viết sẵn từng câu lệnh.

1.2. Tìm phần giống nhau

  • Công việc lặp lại: in i và cộng i vào tổng.
  • Giá trị thay đổi: i tăng từ 1 đến n.
  • Điều kiện dừng: i vượt quá n.
Khởi tạo i → kiểm tra → chạy thân → cập nhật i → quay lại kiểm tra
Kết luận: Vòng lặp mô tả một quy trình lặp, không chỉ là cách viết code ngắn hơn.

2. Vòng lặp for

for (khởi_tạo; điều_kiện; cập_nhật) { thân_vòng_lặp }

Khởi tạo

int i = 1

Điều kiện

i <= n

Cập nhật

i++

2.1. Mô phỏng từng bước

i?
i ≤ n?
Hành động?
Cập nhật?

Output

for (int i = 1;
i <= n;
i++) {
cout << i << ' ';
}

3. Vòng lặp while

while (điều_kiện) { thân_vòng_lặp; cập_nhật; }

Khi nào dùng?

  • Chưa biết trước số lần lặp.
  • Lặp đến dữ liệu dừng.
  • Biến đổi một số cho đến 0.

Ví dụ

while (n > 0) {
    digitSum += n % 10;
    n /= 10;
}

3.1. Mô phỏng tổng chữ số

n?
n % 10?
sum0
n > 0?

4. Vòng lặp do-while

do {
    // công việc
} while (condition);

Điều kiện được kiểm tra sau thân vòng lặp, nên thân chạy ít nhất một lần.

Ví dụ phù hợp: hiển thị menu ít nhất một lần rồi hỏi có tiếp tục hay không.

5. Biến đếm và biến tích lũy

Đếm

count++;

Tổng

sum += x;

Tích

product *= x;

5.1. Mô phỏng tổng 1 đến n

Bất biến: Sau khi xử lý xong i, sum bằng tổng từ 1 đến i.

6. break và continue

break

Dừng ngay vòng lặp gần nhất.

if (x == target) break;

continue

Bỏ phần còn lại của lượt hiện tại.

if (x < 0) continue;
Trong while: nếu continue xảy ra trước câu lệnh cập nhật, biến điều khiển có thể không đổi và gây vòng lặp vô hạn.

7. Vòng lặp lồng nhau

Vòng trong chạy đầy đủ cho mỗi lượt của vòng ngoài.

Vòng ngoài n lần, vòng trong m lần mỗi lượt → O(nm)

8. Phân tích thuật toán

MẫuSố lượtĐộ phức tạpVí dụ
for(i=0;inO(n)Duyệt mảng.
for(i=1;i<=n;i*=2)≈ log₂nO(log n)Nhân đôi biến.
Hai vòng liên tiếpn+nO(n)Hai lượt duyệt.
Hai vòng lồng n×nO(n²)Duyệt mọi cặp.
while chia n cho 10Số chữ sốO(log₁₀n)Xử lý chữ số.

9. Code mẫu

#include 
using namespace std;
int main(){
    int n; cin >> n;
    for(int i=1;i<=n;i++) cout << i << ' ';
}
long long n, sum = 0;
cin >> n;
for(long long i=1;i<=n;i++) sum += i;
cout << sum;
long long n;
cin >> n;
n = llabs(n);
int digitSum = 0;
do {
    digitSum += n % 10;
    n /= 10;
} while(n > 0);
cout << digitSum;
for(int i=0;i> x;
    if(x < 0) continue;
    if(x == target) { found = true; break; }
}
for(int i=1;i<=rows;i++) {
    for(int j=1;j<=columns;j++) {
        cout << '(' << i << ',' << j << ") ";
    }
    cout << '
'; }

10. Giải thích code

10.1. Vì sao for có thể không chạy lần nào?

Điều kiện được kiểm tra trước thân vòng lặp. Nếu sai ngay từ đầu, thân không chạy.

10.2. Vì sao tổng khởi tạo bằng 0?

0 là phần tử trung hòa của phép cộng.

10.3. Vì sao tích khởi tạo bằng 1?

Nếu bằng 0 thì mọi lần nhân sau vẫn bằng 0.

10.4. Vì sao tổng chữ số dùng do-while?

Với n=0, vẫn cần xử lý một chữ số 0.

10.5. For có nhanh hơn while không?

Không. Hiệu năng phụ thuộc số lượt và công việc bên trong, không phụ thuộc tên vòng lặp.

11. Lỗi thường gặp

  • Nhầm i với i<=n.
  • Quên cập nhật biến trong while.
  • Đặt dấu ; sau for/while.
  • Khởi tạo tổng hoặc tích sai.
  • Dùng int cho tổng lớn.
  • Continue làm bỏ qua cập nhật.
  • Cho rằng hai vòng liên tiếp là O(n²).
  • Vòng lặp lồng quá lớn gây TLE.

12. Quiz và bài tập

Câu 1. Vòng nào chạy thân ít nhất một lần?
Câu 2. for(int i=0;i chạy bao nhiêu lượt?
Câu 3. Hai vòng O(n) liên tiếp có tổng độ phức tạp?

📘 Cơ bản

  1. In 1..n và n..1.
  2. Tổng số chẵn ≤n.
  3. Đếm chữ số.

📗 Trung bình

  1. Tính n!.
  2. Kiểm tra số nguyên tố.
  3. UCLN bằng Euclid.

📙 Nâng cao

  1. Bảng cửu chương.
  2. Vẽ hình.
  3. Đếm ước O(√n).

🐣 Học tiếp

  1. Mảng.
  2. Chuỗi.
  3. Độ phức tạp.
Elearning CodePath – CTP Online Judge
Nguyễn Trung Chiến – THPT chuyên Trần Phú
© 2025 | Powered by Django