Bài 5.611 phút đọc
break
Sau bài này bạn sẽ làm được
- Dùng break để thoát switch và thoát vòng lặp
- Giải thích vì sao break chỉ thoát một tầng gần nhất
- Thoát nhiều tầng bằng cờ hoặc bằng goto
break làm đúng một việc: thoát khỏi cấu trúc bao quanh nó gần nhất. Điều gây nhầm lẫn là nó chỉ thoát một tầng, nên trong vòng lặp lồng nhau, nó không làm điều mà nhiều người mong đợi.
#Hai vai trò của break
break dùng được ở đúng hai chỗ: trong switch và trong vòng lặp.
Trong switch: kết thúc một nhánh
switch (x) {
case 1:
printf("Một\n");
break; /* nếu thiếu, luồng rơi xuống case 2 */
case 2:
printf("Hai\n");
break;
}Trong vòng lặp: dừng sớm
/* Tìm phần tử, dừng ngay khi thấy */
long vi_tri = -1;
for (size_t i = 0; i < n; ++i) {
if (a[i] == muc_tieu) {
vi_tri = (long)i;
break; /* không cần duyệt tiếp */
}
}
if (vi_tri >= 0) {
printf("Tìm thấy tại %ld\n", vi_tri);
} else {
printf("Không tìm thấy\n");
}#Chỉ thoát một tầng
Đây là điểm quan trọng nhất của bài.
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (j == 1) {
break; /* chỉ thoát vòng j */
}
printf("%d,%d ", i, j);
}
}
/* In ra: 0,0 1,0 2,0
Vòng ngoài vẫn chạy đủ ba lần. */#Thoát nhiều tầng
C không có break kèm nhãn như một số ngôn ngữ khác. Có ba cách thay thế.
Cách 1: dùng cờ
int xong = 0;
for (int i = 0; i < n && !xong; ++i) {
for (int j = 0; j < m; ++j) {
if (a[i][j] == muc_tieu) {
xong = 1;
break;
}
}
}Cách này dễ hiểu nhưng phải kiểm tra cờ ở điều kiện của mọi vòng lặp bên ngoài, khá dài dòng khi lồng ba tầng trở lên.
Cách 2: dùng goto
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (a[i][j] == muc_tieu) {
goto tim_thay;
}
}
}
printf("Không tìm thấy\n");
goto ket_thuc;
tim_thay:
printf("Tìm thấy\n");
ket_thuc: ;Cách 3: tách thành hàm riêng
int tim(int a[][M], int n, int muc_tieu, int *hang, int *cot)
{
for (int i = 0; i < n; ++i) {
for (int j = 0; j < M; ++j) {
if (a[i][j] == muc_tieu) {
*hang = i;
*cot = j;
return 1; /* return thoát khỏi MỌI tầng vòng lặp */
}
}
}
return 0;
}#Khi nào nên dùng
Duyệt hết vô ích
int tim_thay = 0;
for (size_t i = 0; i < n; ++i) {
if (a[i] == x) {
tim_thay = 1;
}
}
/* Vẫn duyệt hết mảng dù đã tìm thấy ở phần tử đầu tiên. */Dừng khi đã đủ
int tim_thay = 0;
for (size_t i = 0; i < n; ++i) {
if (a[i] == x) {
tim_thay = 1;
break;
}
}Tự làm thử
- Viết chương trình tìm phần tử đầu tiên chia hết cho 7 trong một mảng, dùng
breakđể dừng sớm. Đếm số lần lặp thực tế. - Viết vòng lặp lồng hai tầng, dùng
breakở vòng trong, quan sát vòng ngoài vẫn chạy tiếp. - Tái hiện bẫy
breaktrongswitchnằm trongwhile, quan sát vòng lặp vô hạn, rồi sửa bằng cờ. - Tìm một giá trị trong ma trận hai chiều bằng cả ba cách: dùng cờ, dùng
goto, và tách thành hàm riêng. So sánh độ dễ đọc. - Viết lại một vòng lặp có
breakthành vòng lặp có điều kiện dừng nằm trong phần điều kiện, so sánh hai cách.
Trình chấm điểm tự động sẽ được bổ sung ở giai đoạn sau. Hiện tại bạn tự chạy thử trên máy.
Tóm tắt
- break thoát khỏi switch hoặc vòng lặp bao quanh gần nhất.
- Nó chỉ thoát một tầng, nên trong vòng lặp lồng nhau chỉ thoát vòng trong cùng.
breaktrongswitchnằm trong vòng lặp chỉ thoátswitch, không thoát vòng lặp.- Thoát nhiều tầng bằng cờ, bằng goto tiến về phía trước, hoặc tách thành hàm rồi return.
- Tách thành hàm thường là cách tốt nhất vì return thoát khỏi mọi tầng.
- Đừng rải quá nhiều break, nếu diễn đạt được điều kiện dừng ngay ở đầu vòng lặp thì tốt hơn.