🔄 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
// 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
// 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
// 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
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)
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
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
// 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
// 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
#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
#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
#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
#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:
#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:
#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:
#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:
#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,khoặcrow,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!