Bài 5.5: Bài tập thực hành vòng lặp cơ bản trong C++

Bài 5.5: Bài tập thực hành vòng lặp cơ bản trong C++
Chào mừng trở lại với series blog về lập trình C++! Sau khi đã làm quen với các khái niệm cơ bản như biến, kiểu dữ liệu và cấu trúc điều khiển rẽ nhánh (if-else
, switch
), chúng ta thường gặp phải một nhu cầu phổ biến trong lập trình: thực hiện đi thực hiện lại một đoạn mã nhiều lần.
Hãy tưởng tượng bạn cần in ra dòng chữ "Xin chào!" 10 lần. Liệu bạn có viết câu lệnh cout << "Xin chào!\n";
10 lần không? Chắc chắn là không nếu con số đó lớn hơn, ví dụ 1000 lần! Đây chính là lúc vòng lặp (loops) trở thành người bạn đồng hành không thể thiếu của chúng ta.
Vòng lặp cho phép chúng ta lặp đi lặp lại một khối lệnh dựa trên một điều kiện nhất định. Trong C++, chúng ta có ba loại vòng lặp cơ bản:
- Vòng lặp
for
- Vòng lặp
while
- Vòng lặp
do-while
Mỗi loại có cú pháp và cách hoạt động hơi khác nhau, phù hợp với từng kịch bản cụ thể. Hôm nay, chúng ta sẽ cùng nhau đi sâu vào từng loại, xem các ví dụ minh họa và thực hành để nắm vững chúng nhé!
1. Vòng lặp for
Vòng lặp for
thường được sử dụng khi bạn đã biết trước số lần lặp hoặc khi bạn muốn lặp qua một dãy giá trị có quy luật. Cú pháp của nó khá rõ ràng và gom tất cả các yếu tố điều khiển vòng lặp vào một dòng duy nhất:
for (khởi tạo; điều kiện; cập nhật) {
// Khối lệnh sẽ được thực hiện lặp đi lặp lại
}
khởi tạo
: Được thực hiện một lần duy nhất ở đầu vòng lặp. Thường dùng để khởi tạo biến đếm.điều kiện
: Được kiểm tra trước mỗi lần lặp. Nếu điều kiện đúng (true
), khối lệnh bên trong vòng lặp sẽ được thực thi. Nếu điều kiện sai (false
), vòng lặp sẽ kết thúc.cập nhật
: Được thực hiện sau mỗi lần lặp. Thường dùng để tăng hoặc giảm biến đếm.
Hãy xem một ví dụ kinh điển: In ra các số từ 1 đến 5.
#include <iostream>
int main() {
cout << "Cac so tu 1 den 5 voi vong lap for:\n";
for (int i = 1; i <= 5; ++i) {
cout << i << " ";
}
cout << "\n"; // In xuong dong ket thuc
return 0;
}
Giải thích:
int i = 1;
: Khởi tạo biến đếmi
với giá trị ban đầu là 1.i <= 5;
: Điều kiện lặp. Vòng lặp sẽ tiếp tục chạy chừng nàoi
còn nhỏ hơn hoặc bằng 5.++i;
: Cập nhật biến đếm. Sau mỗi lần lặp,i
sẽ tăng lên 1.- Khối lệnh
{ cout << i << " "; }
sẽ in giá trị hiện tại củai
và một dấu cách.
Kết quả chạy đoạn code trên sẽ là: Cac so tu 1 den 5 voi vong lap for: 1 2 3 4 5
Bạn cũng có thể lặp ngược hoặc bỏ qua các phần trong cú pháp for
(mặc dù không nên lạm dụng để tránh khó hiểu). Ví dụ lặp ngược từ 5 về 1:
#include <iostream>
int main() {
cout << "Dem nguoc tu 5 ve 1 voi vong lap for:\n";
for (int j = 5; j > 0; --j) { // Khoi tao j=5, dieu kien j > 0, cap nhat --j (giam j di 1)
cout << j << " ";
}
cout << "\n";
return 0;
}
Kết quả: Dem nguoc tu 5 ve 1 voi vong lap for: 5 4 3 2 1
Vòng lặp for
rất linh hoạt và là lựa chọn hàng đầu khi bạn có một phạm vi lặp rõ ràng.
2. Vòng lặp while
Không giống như for
, vòng lặp while
được sử dụng khi bạn chưa biết trước số lần lặp cụ thể, mà chỉ biết rằng vòng lặp sẽ tiếp tục chạy chừng nào một điều kiện nào đó còn đúng. Cú pháp của nó đơn giản hơn:
while (điều kiện) {
// Khối lệnh sẽ được thực hiện lặp đi lặp lại
// Đảm bảo có sự thay đổi làm cho điều kiện cuối cùng sai
}
điều kiện
: Được kiểm tra trước mỗi lần lặp. Nếu điều kiện đúng (true
), khối lệnh bên trong sẽ được thực thi. Nếu sai (false
), vòng lặp dừng lại.
Lưu ý quan trọng: Điều kiện của vòng lặp while
cần phải có khả năng trở nên sai sau một số lần lặp. Nếu không, bạn sẽ rơi vào vòng lặp vô hạn (infinite loop), khiến chương trình bị treo! Bạn phải đảm bảo có một logic nào đó bên trong khối lệnh của while
làm thay đổi các yếu tố ảnh hưởng đến điều kiện.
Ví dụ: In ra các số từ 1 đến 5 sử dụng while
.
#include <iostream>
int main() {
cout << "Cac so tu 1 den 5 voi vong lap while:\n";
int count = 1; // Khoi tao bien dem truoc vong lap
while (count <= 5) { // Kiem tra dieu kien
cout << count << " ";
count++; // Cap nhat bien dem ben trong vong lap
}
cout << "\n";
return 0;
}
Giải thích:
- Biến
count
được khởi tạo trước vòng lặp. - Điều kiện
count <= 5
được kiểm tra. Ban đầu là1 <= 5
(đúng). - Khối lệnh được thực thi: in
1
và tăngcount
lên 2. - Lặp lại:
count <= 5
(2 <= 5, đúng). In2
, tăngcount
lên 3... cho đến khicount
là 6. - Khi
count
là 6, điều kiện6 <= 5
là sai, vòng lặp kết thúc.
Kết quả tương tự như vòng lặp for
ở trên: Cac so tu 1 den 5 voi vong lap while: 1 2 3 4 5
Một trường hợp sử dụng phổ biến khác của while
là xử lý đầu vào từ người dùng cho đến khi họ nhập một giá trị hợp lệ.
#include <iostream>
#include <limits> // Can thiet cho numeric_limits
int main() {
int age;
cout << "Moi nhap tuoi cua ban (phai la so duong): ";
// Vong lap while de yeu cau nhap lai neu dau vao khong hop le
while (!(cin >> age) || age <= 0) {
cout << "Dau vao khong hop le. Hay nhap lai tuoi (phai la so duong): ";
cin.clear(); // Xoa co loi cua cin
// Bo qua phan con lai cua dong dau vao de tranh lap vo han neu nguoi dung nhap chuoi
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
cout << "Tuoi hop le cua ban la: " << age << "\n";
return 0;
}
Giải thích:
!(cin >> age)
: Kiểm tra xem thao tác đọcage
có thành công không. Nếu người dùng nhập chữ thay vì số, thao tác này sẽ thất bại và trả vềfalse
, khi đó!(false)
sẽ làtrue
, vòng lặp tiếp tục.age <= 0
: Kiểm tra xem tuổi có phải là số dương không. Nếu không, điều kiện này đúng, vòng lặp tiếp tục.- Toàn bộ điều kiện
!(cin >> age) || age <= 0
sẽ đúng nếu hoặc việc đọc số thất bại hoặc số đọc được không phải là số dương. cin.clear();
: Đặt lại trạng thái lỗi củacin
để có thể đọc tiếp.cin.ignore(...);
: Loại bỏ phần còn lại của dòng đầu vào hiện tại, bao gồm cả ký tự xuống dòng, ngăn chặn vòng lặp vô hạn nếu lỗi đọc là do ký tự không phải số.- Vòng lặp chỉ kết thúc khi người dùng nhập một số nguyên dương thành công.
Đây là một ví dụ hay cho thấy sức mạnh của while
trong các tình huống điều kiện phức tạp hoặc phụ thuộc vào yếu tố bên ngoài (như đầu vào người dùng).
3. Vòng lặp do-while
Vòng lặp do-while
rất giống với while
, nhưng có một điểm khác biệt quan trọng: điều kiện của nó được kiểm tra sau khi khối lệnh được thực thi ít nhất một lần.
Cú pháp:
do {
// Khối lệnh sẽ được thực hiện ít nhất một lần
// và lặp đi lặp lại nếu điều kiện đúng
} while (điều kiện); // Lưu ý dấu chấm phẩy ở cuối
- Khối lệnh bên trong
do { ... }
được thực thi trước. - Sau khi khối lệnh chạy xong,
điều kiện
trongwhile (...)
mới được kiểm tra. - Nếu điều kiện đúng (
true
), quá trình lặp lại bắt đầu từdo
. - Nếu điều kiện sai (
false
), vòng lặp kết thúc.
Điểm khác biệt cốt lõi là: vòng lặp do-while
luôn thực thi khối lệnh của nó ít nhất một lần, bất kể điều kiện ban đầu đúng hay sai.
Ví dụ: Sử dụng do-while
để in một thông báo và hỏi người dùng có muốn lặp lại không.
#include <iostream>
int main() {
char choice;
do {
cout << "Ban co thay hoc C++ thu vi khong? (y/n): ";
cin >> choice;
choice = tolower(choice); // Chuyen ve chu thuong de so sanh de hon
} while (choice != 'y' && choice != 'n'); // Lap lai neu nhap khong phai 'y' hoac 'n'
if (choice == 'y') {
cout << "Tuyet voi! Hay tiep tuc nhe!\n";
} else {
cout << "Hay co gang hon mot chut!\n";
}
return 0;
}
Giải thích:
- Khối lệnh bên trong
do { ... }
sẽ chạy lần đầu tiên mà không cần kiểm tra điều kiện gì. Chương trình sẽ in câu hỏi và chờ người dùng nhập lựa chọn. - Sau khi người dùng nhập
choice
, điều kiệnchoice != 'y' && choice != 'n'
được kiểm tra. - Nếu người dùng nhập bất cứ thứ gì khác 'y' hoặc 'n', điều kiện này sẽ đúng, và vòng lặp
do
sẽ chạy lại, yêu cầu nhập lại. - Chỉ khi người dùng nhập 'y' hoặc 'n' (sau khi chuyển về chữ thường), điều kiện mới sai và vòng lặp kết thúc.
Vòng lặp do-while
phù hợp khi bạn cần thực hiện một hành động ít nhất một lần trước khi quyết định có lặp lại nó dựa trên kết quả của hành động đó hay không.
4. Điều khiển vòng lặp với break và continue
Đôi khi, bên trong một vòng lặp, chúng ta cần thay đổi luồng thực thi bình thường của nó. C++ cung cấp hai câu lệnh để làm điều này: break
và continue
.
break
Câu lệnh break
được sử dụng để thoát ngay lập tức khỏi vòng lặp chứa nó (có thể là for
, while
hoặc do-while
) mà không cần quan tâm đến điều kiện lặp. Việc thực thi chương trình sẽ tiếp tục ở câu lệnh ngay sau vòng lặp.
break
rất hữu ích khi bạn tìm thấy điều mình cần và không muốn tiếp tục lặp nữa.
Ví dụ: Tìm số đầu tiên chia hết cho 7 trong dãy từ 1 đến 100.
#include <iostream>
int main() {
cout << "Tim so chia het cho 7 dau tien tu 1 den 100:\n";
int found_number = -1; // Bien luu ket qua, -1 la khong tim thay
for (int i = 1; i <= 100; ++i) {
if (i % 7 == 0) { // Kiem tra xem i co chia het cho 7 khong
found_number = i; // Neu co, luu lai so do
break; // Thoat khoi vong lap ngay lap tuc
}
}
if (found_number != -1) {
cout << "So dau tien chia het cho 7 la: " << found_number << "\n";
} else {
cout << "Khong tim thay so nao chia het cho 7 trong day!\n"; // Truong hop nay khong xay ra voi day 1-100
}
return 0;
}
Giải thích:
- Vòng lặp
for
bắt đầu từ 1 và chạy đến 100. - Bên trong vòng lặp, câu lệnh
if (i % 7 == 0)
kiểm tra tính chia hết. - Khi
i
bằng 7, điều kiệnif
đúng.found_number
được gán giá trị 7. - Câu lệnh
break;
được thực thi. Vòng lặpfor
dừng lại ngay lập tức, không kiểm tra các số tiếp theo (8, 9, ... 100). - Chương trình nhảy ra khỏi vòng lặp và in kết quả.
continue
Câu lệnh continue
được sử dụng để bỏ qua phần còn lại của lần lặp hiện tại và chuyển sang lần lặp tiếp theo (kiểm tra điều kiện lặp và thực hiện phần cập nhật đối với for
).
continue
hữu ích khi bạn muốn bỏ qua việc xử lý cho một trường hợp cụ thể trong lần lặp đó, nhưng vẫn muốn tiếp tục với các lần lặp tiếp theo của vòng lặp.
Ví dụ: In ra các số lẻ từ 1 đến 10.
#include <iostream>
int main() {
cout << "Cac so le tu 1 den 10:\n";
for (int i = 1; i <= 10; ++i) {
if (i % 2 == 0) { // Kiem tra xem i co phai so chan khong
continue; // Neu la so chan, bo qua phan con lai cua lan lap nay
}
// Dong code nay chi duoc thuc thi neu i la so le
cout << i << " ";
}
cout << "\n";
return 0;
}
Giải thích:
- Vòng lặp
for
duyệt qua các số từ 1 đến 10. - Khi
i
là 1,i % 2 == 0
là sai. Chương trình bỏ quaif
và in1
. - Khi
i
là 2,i % 2 == 0
là đúng. Câu lệnhcontinue;
được thực thi. continue
làm cho chương trình bỏ qua câu lệnhcout << i << " ";
cho lần lặp khii=2
.- Vòng lặp chuyển sang lần lặp tiếp theo với
i
tăng lên 3. - Quá trình này tiếp diễn.
continue
sẽ bỏ qua việc in các số 2, 4, 6, 8, 10.
Kết quả: Cac so le tu 1 den 10: 1 3 5 7 9
Tóm tắt
Bạn đã thấy sức mạnh của các loại vòng lặp cơ bản trong C++:
for
: Lý tưởng cho số lần lặp xác định hoặc duyệt qua một dãy.while
: Phù hợp khi số lần lặp không rõ ràng, chỉ dựa vào một điều kiện tiếp tục. Cẩn thận với vòng lặp vô hạn!do-while
: Đảm bảo khối lệnh chạy ít nhất một lần trước khi kiểm tra điều kiện lặp.
Cùng với đó, break
giúp bạn thoát khẩn cấp khỏi vòng lặp, còn continue
cho phép bạn bỏ qua lần lặp hiện tại để sang lần tiếp theo.
Comments