Mục lục bài họcĐang ở d02-b3
while Loops, for Loops, and Counting Iterations
while
A while loop tests its condition before each pass. If the condition is false at the start, the body never runs at all. Three things must be present or the loop is wrong: an initialisation before the loop, a condition that can become false, and an update inside the body that moves the loop variable toward that condition. Removing the update, or updating a different variable from the one being tested, produces an infinite loop.
for
The header for (init; condition; update) gathers those three parts on one line. Execution order is: run init once, test the condition, run the body, run the update, test again. The loop variable declared in the header exists only inside the loop.
Counting the passes
For for (int i = a; i < b; i++) the body runs b - a times, provided b >= a. Changing < to <= adds exactly one pass. With a step of k, the count is the number of values of i in the range, which is not (b - a) / k in general. When the loop variable indexes a string, the safe upper bound is i < s.length(), because valid indexes run from 0 through s.length() - 1.
while — kiểm tra trước, chạy sau
while xét điều kiện trước mỗi lượt. Điều kiện sai ngay từ đầu thì thân lặp không chạy lần nào. Ba mảnh phải có đủ: khởi tạo trước vòng lặp, điều kiện có khả năng trở thành sai, và bước cập nhật trong thân đẩy biến lặp về phía điều kiện đó. Thiếu bước cập nhật — hoặc cập nhật nhầm sang biến khác với biến đang được xét — là vòng lặp vô hạn.
for — gói ba mảnh vào một dòng
for (khởi tạo; điều kiện; cập nhật) chạy theo thứ tự: khởi tạo một lần, xét điều kiện, chạy thân, cập nhật, rồi xét lại. Biến khai báo trong đầu vòng for chỉ tồn tại bên trong vòng lặp.
Đếm số lượt chạy
Với for (int i = a; i < b; i++) thân chạy b − a lượt (khi b >= a). Đổi < thành <= là cộng thêm đúng một lượt — không nhiều hơn, không ít hơn. Với bước nhảy k, số lượt là số giá trị của i rơi vào khoảng, không phải (b − a) / k. Khi biến lặp dùng làm chỉ số của chuỗi, cận trên an toàn là i < s.length(), vì chỉ số hợp lệ chạy từ 0 tới s.length() - 1.
"HELLO" có length() bằng 5 nhưng chỉ số dùng được chỉ tới 4 — độ dài và chỉ số cuối lệch nhau đúng một. Đổi < thành <= trong điều kiện là kéo vòng lặp thêm một lượt, và lượt đó rơi vào ô đứt nét. Đáng chú ý là lỗi này không phải lúc nào cũng nổ: nếu thân lặp có một câu return chạy trước khi tới lượt cuối thì chương trình thoát êm, nên bug ẩn cho tới khi gặp đúng dữ liệu không kích hoạt return.Đếm số lượt thân lặp chạy, rồi cho biết giá trị in ra.
int total = 0;
int passes = 0;
for (int k = 10; k > 0; k -= 3) {
total += k;
passes++;
}
System.out.println(passes + " " + total);Lập bảng thay vì nhẩm. Bước nhảy âm nên phải liệt kê giá trị của k ở đầu mỗi lượt:
| lượt | k đầu lượt | total sau lượt |
|---|---|---|
| 1 | 10 | 10 |
| 2 | 7 | 17 |
| 3 | 4 | 21 |
| 4 | 1 | 22 |
Sau lượt thứ tư, k thành -2; điều kiện k > 0 sai nên vòng lặp dừng. In ra 4 22.
Vì sao không chia. Công thức (10 − 0) / 3 cho 3 và sai. Với bước nhảy khác 1, số lượt là số giá trị rơi vào khoảng, phải đếm chứ không chia — đúng chỗ này đề AP cài bẫy nhiều nhất.
i <= s.length() khi duyệt chuỗi. Nó chạy thừa đúng một lượt và ném StringIndexOutOfBoundsException — nhưng chỉ với những dữ liệu khiến vòng lặp chạy hết, nên bài kiểm thử sơ sài vẫn xanh. Cách chặn: mỗi vòng lặp duyệt chuỗi phải viết ra giá trị lớn nhất mà biến lặp nhận được, rồi so với s.length() - 1. Lớn hơn là hỏng.while xét trước, có thể chạy không lượt nào. for (i = a; i < b; i++) chạy đúng b − a lượt; đổi sang <= là thêm một lượt. Bước nhảy khác 1 thì đếm, đừng chia.Đọc xong rồi — làm thử ngay
Bài tập của chương Unit 2 — Selection and Iteration gồm 14 câu trắc nghiệm và 8 đề tự luận. Đáp án hiện ngay khi chọn, miễn phí.