Mục lục bài họcĐang ở d02-b3
← AP Computer Science A
0/16 bài đã học xong
Chương 2 · Unit 2 — Selection and Iteration · Bài 3/4 của chương · bài 7/16 của AP Computer Science A

while Loops, for Loops, and Counting Iterations

Vòng lặp while, for và cách đếm số lượt
← Mục lục bài học
Lý thuyết · English

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.

Giải thích tiếng Việt

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?012345i < s.length() cho đúng 5 lượt: 0,1,2,3,4i <= s.length() thêm đúng MỘT lượt — lượt i = 5 vượt biên.s.length() là 5, nhưng chỉ số cuối cùng dùng được là 4.substring(5, 6) ném StringIndexOutOfBoundsException.
Ô đứt nét là toàn bộ lỗi lệch một đơn vị. Chuỗi "HELLO"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.
Ví dụ — đếm lượt với bước nhảy âm

Đế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);
Giải.

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ượtk đầu lượttotal sau lượt
11010
2717
3421
4122

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.

Bẫy hay mất điểm — Lỗi đắt nhất: dùng 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.
Phải nhớ — 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í.

Làm bài tập chương →