Vòng lặp for trong C là cấu trúc dùng để lặp lại một khối lệnh với số lần xác định. Bạn sẽ dùng nó để duyệt mảng, tính tổng, in bảng hay xử lý dữ liệu từng phần tử. Bài này giải thích cấu trúc ba phần của for, luồng chạy từng bước và những lỗi thường làm người mới mất thời gian.
Cấu trúc của vòng lặp for

#include <stdio.h>
int main(void) {
for (int i = 1; i <= 5; i++) {
printf("%d ", i);
}
printf("n"); // 1 2 3 4 5
return 0;
}
Trong ngoặc của for có ba phần ngăn cách bằng dấu chấm phẩy. Phần khởi tạo chạy một lần duy nhất ở đầu. Phần điều kiện được kiểm tra trước mỗi lượt. Phần bước nhảy chạy sau mỗi lượt, thường để tăng hoặc giảm biến đếm.
Khai báo biến ngay trong for như int i = 1 chỉ hợp lệ từ chuẩn C99 trở đi. Với trình biên dịch cũ hoặc cờ -std=c89, bạn phải khai báo biến trước vòng lặp.
Luồng chạy từng bước

Để hiểu rõ, hãy đi theo ví dụ trên. Bước một, i được gán 1. Bước hai, kiểm tra 1 <= 5 đúng nên chạy thân và in số 1. Bước ba, thực hiện i++, i thành 2.
Sau đó quay lại kiểm tra điều kiện. Khi i bằng 6, điều kiện sai và vòng lặp dừng. Chương trình chạy tiếp lệnh sau for.
Một chi tiết hay bị bỏ qua: nếu điều kiện sai ngay lần kiểm tra đầu tiên, thân vòng lặp không chạy lần nào. Đây là khác biệt giữa for và do-while, thứ luôn chạy ít nhất một lần.
Duyệt mảng và tính tổng

int diem[] = {7, 8, 6, 9, 5};
int n = sizeof(diem) / sizeof(diem[0]);
int tong = 0;
for (int i = 0; i < n; i++) {
tong += diem[i];
}
printf("Trung bình: %.2fn", (double)tong / n);
Công thức sizeof(diem) / sizeof(diem[0]) cho số phần tử của mảng. Nó chỉ đúng khi diem là mảng thật chứ không phải con trỏ nhận qua tham số hàm. Điểm này liên quan trực tiếp tới con trỏ trong C, và bạn sẽ hiểu rõ hơn khi đọc bài đó.
Chú ý ép kiểu (double)tong trước khi chia. Nếu không, phép chia hai số nguyên cho kết quả nguyên và phần thập phân bị cắt mất.
Vòng lặp lồng nhau

for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
printf("%dt", i * j);
}
printf("n");
}
Vòng ngoài chạy ba lượt, và với mỗi lượt vòng trong chạy đủ ba lượt, tổng cộng chín lần in. Khi lồng, hãy dùng các biến đếm khác tên nhau. Nếu dùng chung một biến, vòng trong sẽ làm hỏng giá trị của vòng ngoài.
break và continue
Lệnh break thoát hẳn vòng lặp, còn continue bỏ qua phần còn lại của lượt hiện tại và nhảy sang lượt kế tiếp.
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) continue; // bỏ qua số chẵn
if (i > 7) break; // dừng khi vượt 7
printf("%d ", i); // 1 3 5 7
}
Trong vòng lặp lồng nhau, break chỉ thoát vòng trong cùng. Muốn thoát nhiều tầng, bạn có thể dùng biến cờ hoặc tách phần lặp ra thành một hàm riêng rồi return.
Lỗi thường gặp
- Lệch một đơn vị khi dùng
<=với mảng, dẫn tới truy cập ngoài phạm vi và hành vi không xác định. - Chấm phẩy thừa sau ngoặc for làm thân vòng lặp bị rỗng.
- Vòng lặp vô hạn do quên cập nhật biến đếm hoặc cập nhật sai chiều.
- Thay đổi biến đếm bên trong thân vòng lặp làm khó theo dõi.
C không kiểm tra truy cập ngoài mảng. Chương trình có thể vẫn chạy và in ra giá trị rác, hoặc đột ngột dừng với lỗi segmentation fault. Vì vậy hãy luôn kiểm tra kỹ giới hạn của vòng lặp.
Nếu thân vòng lặp cần rẽ nhánh, hãy kết hợp với câu lệnh if trong C. Và nếu bạn muốn so sánh với cách viết ở ngôn ngữ khác, bài vòng lặp for trong Java có cú pháp rất gần. Tài liệu chuẩn tại cppreference.com.
Hỏi đáp nhanh về vòng lặp for
Có thể bỏ trống cả ba phần của for không?
Có, for (;;) là vòng lặp vô hạn. Người ta dùng nó khi muốn lặp mãi. Lối thoát nằm bên trong bằng break hay return, ví dụ vòng lặp chính của một chương trình đọc lệnh từ bàn phím.
Có thể chạy for đếm ngược không?
Hoàn toàn được. Viết for (int i = 10; i > 0; i--) để đi từ 10 xuống 1. Khi đếm ngược với số không dấu như size_t, hãy cẩn thận: điều kiện i >= 0 luôn đúng vì số không dấu không âm, và vòng lặp sẽ chạy mãi.
Chọn for hay while?
Dùng for khi bạn biết số lần lặp hoặc có biến đếm rõ ràng. Dùng while khi bạn lặp đến lúc một điều kiện nào đó thay đổi, chẳng hạn đọc đến khi hết tệp. Hai vòng lặp có sức mạnh tương đương, chỉ khác ở độ rõ ràng khi đọc code.
Một mẹo nhỏ để gỡ lỗi: nếu vòng lặp cho kết quả lạ, hãy thêm một dòng printf in giá trị biến đếm ở đầu thân vòng lặp. Cách này đơn giản nhưng giúp bạn thấy ngay vòng lặp chạy qua những giá trị nào. Khi đã quen cú pháp, bạn có thể so sánh với cách duyệt mảng trong JavaScript để thấy sự khác nhau giữa các ngôn ngữ.
Bài tập: in tam giác sao có chiều cao nhập từ bàn phím bằng hai vòng for lồng nhau. Sau đó thử đảo ngược tam giác để nắm vững vai trò của từng biến đếm.



