Bỏ qua điều hướng, tới nội dung chính
Học C
Bài 5.711 phút đọc

continue

Sau bài này bạn sẽ làm được

  • Dùng continue để bỏ qua các phần tử không hợp lệ
  • Giải thích bẫy continue làm mất bước tăng biến trong while
  • Phân biệt rõ break với continue

continue bỏ qua phần còn lại của lượt lặp hiện tại và nhảy sang lượt tiếp theo. Nó rất tiện khi lọc dữ liệu, nhưng có một cạm bẫy làm vòng lặp while chạy vô hạn mà nhiều người mất khá lâu mới tìm ra.

#Ý nghĩa

for (int i = 1; i <= 10; ++i) {
    if (i % 2 == 0) {
        continue;           /* bỏ qua số chẵn */
    }

    printf("%d ", i);
}

/* In ra: 1 3 5 7 9 */

Khi gặp continue, luồng nhảy thẳng tới phần cập nhật của vòng lặp, tức là ++i, rồi kiểm tra điều kiện và bắt đầu lượt mới. Mọi câu lệnh phía dưới trong thân vòng lặp bị bỏ qua.

Cách viết này tương đương với việc bọc phần thân trong một if, nhưng nó giữ mã ở mức thụt lề thấp, đúng tinh thần guard clause đã học ở Bài 5.4.

Lồng sâu
for (size_t i = 0; i < n; ++i) {
    if (a[i] >= 0) {
        if (a[i] < 100) {
            if (a[i] % 2 == 0) {
                xu_ly(a[i]);
            }
        }
    }
}
Phẳng nhờ continue
for (size_t i = 0; i < n; ++i) {
    if (a[i] < 0)       continue;
    if (a[i] >= 100)    continue;
    if (a[i] % 2 != 0)  continue;

    xu_ly(a[i]);
}

#Bẫy trong while

Đây là nội dung quan trọng nhất của bài. Với for, phần cập nhật nằm ở đầu vòng lặp nên continue vẫn chạy qua nó. Với while, phần cập nhật nằm trong thân, nên continue bỏ qua luôn.

Không nên
int i = 0;

while (i < 10) {
    if (i % 2 == 0) {
        continue;       /* i KHÔNG BAO GIỜ tăng */
    }

    printf("%d ", i);
    i++;
}

/* Vòng lặp vô hạn.
   Khi i bằng 0, continue nhảy về đầu,
   i vẫn bằng 0, lại continue, mãi mãi. */
Nên
int i = 0;

while (i < 10) {
    int hien_tai = i;

    i++;                /* tăng TRƯỚC khi có thể continue */

    if (hien_tai % 2 == 0) {
        continue;
    }

    printf("%d ", hien_tai);
}

#So sánh với break

breakcontinue
Tác dụngThoát hẳn vòng lặpSang lượt lặp tiếp theo
Dùng được trong switchKhông
Số tầng thoátMột tầng gần nhấtMột tầng gần nhất
Trong forKhông chạy phần cập nhậtCÓ chạy phần cập nhật
Trong whileThoát ngayBỏ qua mọi thứ còn lại, kể cả phần tăng biến
for (int i = 0; i < 5; ++i) {
    if (i == 2) {
        continue;
    }

    printf("%d ", i);
}
printf("\n");
/* In ra: 0 1 3 4  (bỏ qua 2, vẫn chạy hết) */

for (int i = 0; i < 5; ++i) {
    if (i == 2) {
        break;
    }

    printf("%d ", i);
}
printf("\n");
/* In ra: 0 1  (dừng hẳn tại 2) */

#Khi nào nên dùng

continue hữu ích nhất khi bạn muốn lọc bỏ một số phần tử và phần xử lý chính khá dài.

doc-file.c
char dong[256];
size_t so_dong = 0, so_bo_qua = 0;

while (fgets(dong, sizeof dong, f)) {
    ++so_dong;

    dong[strcspn(dong, "\n")] = '\0';

    if (dong[0] == '\0') {
        ++so_bo_qua;
        continue;                  /* bỏ qua dòng trống */
    }

    if (dong[0] == '#') {
        ++so_bo_qua;
        continue;                  /* bỏ qua dòng chú thích */
    }

    /* Phần xử lý chính, có thể dài vài chục dòng,
       và nó không bị thụt lề thêm tầng nào. */
    phan_tich_dong(dong);
}

Tự làm thử

  1. In các số từ 1 tới 50 nhưng bỏ qua những số chia hết cho 3 hoặc chia hết cho 5.
  2. Tái hiện vòng lặp vô hạn bằng continue trong while, rồi sửa bằng hai cách khác nhau.
  3. Viết chương trình đọc file, đếm số dòng có nội dung, bỏ qua dòng trống và dòng bắt đầu bằng dấu thăng.
  4. Tính trung bình cộng của các số dương trong mảng, dùng continue để bỏ qua số âm và số 0.
  5. Viết một vòng lặp có cả breakcontinue, giải thích luồng chạy bằng lời.
  6. Đặt continue trong switch nằm trong while, quan sát nó tác động lên vòng lặp chứ không phải switch.

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

  • continue bỏ qua phần còn lại của lượt lặp và sang lượt tiếp theo.
  • Trong for, phần cập nhật vẫn chạy. Trong while, nó bị bỏ qua luôn.
  • Đây là nguyên nhân vòng lặp while có continue dễ chạy vô hạn.
  • Khi có biến đếm, dùng for để phần cập nhật không bao giờ bị bỏ sót.
  • continue trong switch tác động lên vòng lặp bao ngoài, không phải lên switch.
  • Dùng continue khi cần lọc bỏ và phần xử lý chính dài. Thân ngắn thì if thuận rõ hơn.