Skip to content

🔄 Vòng lặp trong C++

📖 Giới thiệu

Vòng lặp (loops) là cấu trúc cho phép thực thi một đoạn code nhiều lần. Thay vì phải viết cùng một đoạn code berulang lại, chúng ta có thể sử dụng vòng lặp để máy tính tự động thực hiện công việc lặp đi lặp lại.

Trong cuộc sống, chúng ta thường gặp các hoạt động lặp lại: đếm từ 1 đến 100, in 50 trang tài liệu, kiểm tra từng học sinh trong lớp. Lập trình cũng vậy - vòng lặp giúp chúng ta xử lý các tác vụ tương tự một cách hiệu quả.

C++ cung cấp ba loại vòng lặp chính: for (biết trước số lần lặp), while (lặp khi điều kiện đúng), và do-while (lặp ít nhất một lần rồi kiểm tra điều kiện).

🔧 Cú pháp

Vòng lặp for

cpp
// Cú pháp cơ bản
for (khởi_tạo; điều_kiện; cập_nhật) {
    // Code thực thi trong mỗi lần lặp
}

// Ví dụ cụ thể
for (int i = 0; i < 10; i++) {
    cout << i << " ";
}

Vòng lặp while

cpp
// Cú pháp
while (điều_kiện) {
    // Code thực thi
    // Cần có câu lệnh cập nhật để tránh vòng lặp vô hạn
}

// Ví dụ
int i = 0;
while (i < 10) {
    cout << i << " ";
    i++;  // Cập nhật để tránh vòng lặp vô hạn
}

Vòng lặp do-while

cpp
// Cú pháp
do {
    // Code thực thi (chạy ít nhất 1 lần)
} while (điều_kiện);

// Ví dụ
int i = 0;
do {
    cout << i << " ";
    i++;
} while (i < 10);

Từ khóa break và continue

cpp
for (int i = 0; i < 10; i++) {
    if (i == 5) {
        break;     // Thoát khỏi vòng lặp ngay lập tức
    }
    if (i % 2 == 0) {
        continue;  // Bỏ qua phần còn lại, chuyển sang lần lặp tiếp theo
    }
    cout << i << " ";
}

Vòng lặp lồng nhau (Nested loops)

cpp
for (int i = 1; i <= 3; i++) {
    for (int j = 1; j <= 3; j++) {
        cout << "(" << i << "," << j << ") ";
    }
    cout << endl;
}

🔬 Phân tích & Giải thích chi tiết

Khi nào dùng loại vòng lặp nào?

For loop - Khi biết trước số lần lặp:

  • Duyệt mảng: for (int i = 0; i < n; i++)
  • Đếm số: for (int i = 1; i <= 100; i++)
  • Lặp theo pattern cố định

While loop - Khi điều kiện là chính:

  • Đọc input đến khi gặp giá trị đặc biệt
  • Lặp đến khi đạt được mục tiêu
  • Xử lý menu (lặp đến khi user chọn thoát)

Do-while loop - Khi cần thực thi ít nhất 1 lần:

  • Menu phải hiện ít nhất 1 lần
  • Nhập liệu với validation
  • Game loop (chơi ít nhất 1 lần)

Cấu trúc for loop chi tiết

cpp
for (int i = 0; i < 10; i++) {
//   ^khởi tạo  ^điều kiện  ^cập nhật
    cout << i;
}

// Tương đương với:
int i = 0;           // Khởi tạo
while (i < 10) {     // Điều kiện
    cout << i;       // Thân vòng lặp
    i++;             // Cập nhật
}

Vòng lặp vô hạn và cách tránh

cpp
// VÔ HẠN - Thiếu cập nhật
int i = 0;
while (i < 10) {
    cout << i;
    // Thiếu i++; → i luôn = 0 → điều kiện luôn đúng
}

// VÔ HẠN - Cập nhật sai hướng
for (int i = 0; i < 10; i--) {  // i giảm thay vì tăng
    cout << i;
}

// ĐÚNG - Có cập nhật hợp lý
for (int i = 0; i < 10; i++) {
    cout << i;
}

Hiệu suất của các loại vòng lặp

cpp
// For loop - Tối ưu nhất cho đếm
for (int i = 0; i < 1000000; i++) {
    // Compiler có thể tối ưu tốt
}

// While loop - Linh hoạt nhưng có thể chậm hơn
int i = 0;
while (i < 1000000) {
    // Code
    i++;
}

// Range-based for (C++11) - Tối ưu cho container
vector<int> numbers = {1, 2, 3, 4, 5};
for (int num : numbers) {
    cout << num << " ";
}

💻 Ví dụ minh họa

Chương trình bảng cửu chương

cpp
#include <iostream>
#include <iomanip>
using namespace std;

int main() {
    cout << "=== BẢNG CỬU CHƯƠNG ===" << endl;
    
    // Vòng lặp ngoài: các bảng từ 1 đến 10
    for (int table = 1; table <= 10; table++) {
        cout << "\n--- Bảng " << table << " ---" << endl;
        
        // Vòng lặp trong: nhân từ 1 đến 10
        for (int num = 1; num <= 10; num++) {
            cout << setw(2) << table << " x " 
                 << setw(2) << num << " = " 
                 << setw(3) << (table * num) << endl;
        }
    }
    
    return 0;
}

Chương trình menu với do-while

cpp
#include <iostream>
using namespace std;

int main() {
    int choice;
    double balance = 1000000;  // Số dư ban đầu
    
    cout << "=== HỆ THỐNG ATM ===" << endl;
    
    do {
        // Hiển thị menu
        cout << "\n========== MENU ==========" << endl;
        cout << "1. Kiểm tra số dư" << endl;
        cout << "2. Rút tiền" << endl;
        cout << "3. Nạp tiền" << endl;
        cout << "4. Thoát" << endl;
        cout << "=========================" << endl;
        cout << "Chọn chức năng (1-4): ";
        cin >> choice;
        
        switch (choice) {
            case 1: {
                cout << "Số dư hiện tại: " << balance << " VNĐ" << endl;
                break;
            }
            case 2: {
                double amount;
                cout << "Nhập số tiền cần rút: ";
                cin >> amount;
                
                if (amount > balance) {
                    cout << "Lỗi: Số dư không đủ!" << endl;
                } else if (amount <= 0) {
                    cout << "Lỗi: Số tiền phải lớn hơn 0!" << endl;
                } else {
                    balance -= amount;
                    cout << "Rút thành công " << amount << " VNĐ" << endl;
                    cout << "Số dư còn lại: " << balance << " VNĐ" << endl;
                }
                break;
            }
            case 3: {
                double amount;
                cout << "Nhập số tiền cần nạp: ";
                cin >> amount;
                
                if (amount <= 0) {
                    cout << "Lỗi: Số tiền phải lớn hơn 0!" << endl;
                } else {
                    balance += amount;
                    cout << "Nạp thành công " << amount << " VNĐ" << endl;
                    cout << "Số dư hiện tại: " << balance << " VNĐ" << endl;
                }
                break;
            }
            case 4: {
                cout << "Cảm ơn bạn đã sử dụng dịch vụ!" << endl;
                break;
            }
            default: {
                cout << "Lỗi: Lựa chọn không hợp lệ!" << endl;
                break;
            }
        }
        
    } while (choice != 4);  // Lặp đến khi user chọn thoát
    
    return 0;
}

Chương trình vẽ hình với vòng lặp

cpp
#include <iostream>
using namespace std;

int main() {
    int size;
    
    cout << "Nhập kích thước hình: ";
    cin >> size;
    
    cout << "\n1. Hình vuông:" << endl;
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            cout << "* ";
        }
        cout << endl;
    }
    
    cout << "\n2. Tam giác vuông:" << endl;
    for (int i = 1; i <= size; i++) {
        for (int j = 1; j <= i; j++) {
            cout << "* ";
        }
        cout << endl;
    }
    
    cout << "\n3. Tam giác cân:" << endl;
    for (int i = 1; i <= size; i++) {
        // In khoảng trắng
        for (int j = 1; j <= size - i; j++) {
            cout << " ";
        }
        // In dấu *
        for (int j = 1; j <= 2 * i - 1; j++) {
            cout << "*";
        }
        cout << endl;
    }
    
    cout << "\n4. Hình thoi:" << endl;
    // Nửa trên
    for (int i = 1; i <= size; i++) {
        for (int j = 1; j <= size - i; j++) {
            cout << " ";
        }
        for (int j = 1; j <= 2 * i - 1; j++) {
            cout << "*";
        }
        cout << endl;
    }
    // Nửa dưới
    for (int i = size - 1; i >= 1; i--) {
        for (int j = 1; j <= size - i; j++) {
            cout << " ";
        }
        for (int j = 1; j <= 2 * i - 1; j++) {
            cout << "*";
        }
        cout << endl;
    }
    
    return 0;
}

Game đoán số với while loop

cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

int main() {
    // Khởi tạo random seed
    srand(time(0));
    
    int secretNumber = rand() % 100 + 1;  // Số từ 1-100
    int guess;
    int attempts = 0;
    bool hasWon = false;
    
    cout << "=== GAME ĐOÁN SỐ ===" << endl;
    cout << "Tôi đã nghĩ ra một số từ 1 đến 100." << endl;
    cout << "Bạn có thể đoán được không?" << endl;
    
    while (!hasWon && attempts < 7) {  // Tối đa 7 lần đoán
        cout << "\nLần đoán thứ " << (attempts + 1) << ": ";
        cin >> guess;
        attempts++;
        
        if (guess == secretNumber) {
            hasWon = true;
            cout << "🎉 Chúc mừng! Bạn đã đoán đúng!" << endl;
            cout << "Số bí mật là: " << secretNumber << endl;
            cout << "Bạn đã đoán trong " << attempts << " lần!" << endl;
            
            // Đánh giá kết quả
            if (attempts <= 3) {
                cout << "Xuất sắc! Bạn là thiên tài!" << endl;
            } else if (attempts <= 5) {
                cout << "Tốt lắm! Bạn rất thông minh!" << endl;
            } else {
                cout << "Không tệ! May mắn lần sau!" << endl;
            }
        } else if (guess < secretNumber) {
            cout << "Số bạn đoán NHỎ HƠN số bí mật!" << endl;
        } else {
            cout << "Số bạn đoán LỚN HƠN số bí mật!" << endl;
        }
        
        // Hiển thị số lần đoán còn lại
        if (!hasWon && attempts < 7) {
            cout << "Bạn còn " << (7 - attempts) << " lần đoán!" << endl;
        }
    }
    
    if (!hasWon) {
        cout << "\n😞 Hết lượt đoán rồi!" << endl;
        cout << "Số bí mật là: " << secretNumber << endl;
        cout << "Chúc bạn may mắn lần sau!" << endl;
    }
    
    return 0;
}

🏋️ Thực hành

Bài tập 1: Tính tổng và trung bình

Viết chương trình:

  • Nhập n số nguyên
  • Tính tổng và trung bình cộng
  • Đếm số chẵn, số lẻ

Bài tập 2: Vẽ bảng ASCII

Vẽ bảng mã ASCII từ 32 đến 126 với format:

Dec | Hex | Oct | Char
----|-----|-----|-----
 32 | 20  | 40  |  
 33 | 21  | 41  |  !

Bài tập 3: Tìm số nguyên tố

Viết chương trình:

  • Kiểm tra một số có phải số nguyên tố không
  • In ra tất cả số nguyên tố từ 1 đến n

Bài tập 4: Fibonacci sequence

Tính và in dãy Fibonacci:

  • F(0) = 0, F(1) = 1
  • F(n) = F(n-1) + F(n-2)
  • In ra n số đầu tiên của dãy

Lời giải chi tiết

Bài tập 1:

cpp
#include <iostream>
using namespace std;

int main() {
    int n, number;
    int sum = 0, evenCount = 0, oddCount = 0;
    
    cout << "Nhập số lượng số nguyên: ";
    cin >> n;
    
    for (int i = 1; i <= n; i++) {
        cout << "Nhập số thứ " << i << ": ";
        cin >> number;
        
        sum += number;
        
        if (number % 2 == 0) {
            evenCount++;
        } else {
            oddCount++;
        }
    }
    
    double average = (double)sum / n;
    
    cout << "\nKết quả:" << endl;
    cout << "Tổng: " << sum << endl;
    cout << "Trung bình: " << average << endl;
    cout << "Số chẵn: " << evenCount << endl;
    cout << "Số lẻ: " << oddCount << endl;
    
    return 0;
}

Bài tập 2:

cpp
#include <iostream>
#include <iomanip>
using namespace std;

int main() {
    cout << "Dec | Hex | Oct | Char" << endl;
    cout << "----|-----|-----|-----" << endl;
    
    for (int i = 32; i <= 126; i++) {
        cout << setw(3) << dec << i << " | "
             << setw(2) << hex << i << "  | "
             << setw(2) << oct << i << "  | "
             << setw(2) << (char)i << endl;
    }
    
    return 0;
}

Bài tập 3:

cpp
#include <iostream>
using namespace std;

bool isPrime(int n) {
    if (n < 2) return false;
    if (n == 2) return true;
    if (n % 2 == 0) return false;
    
    for (int i = 3; i * i <= n; i += 2) {
        if (n % i == 0) return false;
    }
    return true;
}

int main() {
    int n;
    cout << "Nhập n: ";
    cin >> n;
    
    cout << "Các số nguyên tố từ 1 đến " << n << ":" << endl;
    for (int i = 2; i <= n; i++) {
        if (isPrime(i)) {
            cout << i << " ";
        }
    }
    cout << endl;
    
    return 0;
}

Bài tập 4:

cpp
#include <iostream>
using namespace std;

int main() {
    int n;
    cout << "Nhập số lượng số Fibonacci: ";
    cin >> n;
    
    if (n >= 1) {
        long long fib1 = 0, fib2 = 1;
        cout << "Dãy Fibonacci: " << fib1;
        
        if (n >= 2) {
            cout << " " << fib2;
            
            for (int i = 3; i <= n; i++) {
                long long nextFib = fib1 + fib2;
                cout << " " << nextFib;
                fib1 = fib2;
                fib2 = nextFib;
            }
        }
        cout << endl;
    }
    
    return 0;
}

📋 Tóm tắt

🎯 Những gì đã học

  • For loop: Lặp với số lần cố định, có khởi tạo-điều kiện-cập nhật
  • While loop: Lặp khi điều kiện đúng, cần cẩn thận với vòng lặp vô hạn
  • Do-while loop: Thực thi ít nhất 1 lần rồi mới kiểm tra điều kiện
  • Break/Continue: Điều khiển luồng trong vòng lặp
  • Nested loops: Vòng lặp lồng nhau cho bài toán 2D

🔧 Best Practices

  • Chọn loại vòng lặp phù hợp với bài toán
  • Luôn đảm bảo có điều kiện thoát để tránh vòng lặp vô hạn
  • Sử dụng tên biến có nghĩa cho counter: i, j, k hoặc row, col
  • Kiểm tra điều kiện biên cẩn thận
  • Sử dụng break/continue một cách có ý thức

🚀 Chuẩn bị cho bước tiếp theo

Bài học tiếp theo sẽ tìm hiểu về mảng 1 chiều. Đảm bảo bạn đã:

  • [x] Thành thạo cả 3 loại vòng lặp
  • [x] Hiểu khi nào dùng break/continue
  • [x] Viết được vòng lặp lồng nhau
  • [x] Tránh được vòng lặp vô hạn

💡 Lời khuyên

"Vòng lặp như những cỗ máy - hãy thiết kế chúng cẩn thận với điều kiện dừng rõ ràng!"


Chuyển sang: Mảng 1 chiều để học cách lưu trữ và xử lý nhiều dữ liệu cùng loại!

Khóa học C++ miễn phí