Goto trong lập trình C

Bài 11 : Lệnh goto trong lập trình C

Chào các bạn, chúng ta đã đi qua hết 10 bài, và đây là bài số 11 trong chuỗi seri học lập trình C. Trong bài này mình sẽ chia sẻ với các bạn câu lệnh goto trong lập trình C.

Nếu các bạn chưa xem bài số 10 thì xem tại đây nhé.

Trong bài này mình sẽ chia sẻ cho các bạn là lệnh goto trong lập trình C là như thế nào? nó hoạt động ra sao? Nó dùng để làm gì? Khi nào nên dùng? Khi nào không dùng nhé

1. Lệnh goto trong lập trình C

Trong ngôn ngữ lập trình C, câu lệnh goto cho phép chương trình nhảy tới một vị trí khác trong mã nguồn.

Cú pháp cơ bản của câu lệnh goto trong ngôn ngữ lập trình C:

goto label;
... .. ...
... .. ...
label: 
statement;

Ví dụ : Câu lệnh goto

// Program to calculate the sum and average of positive numbers
// If the user enters a negative number, the sum and average are displayed.

#include <stdio.h>

int main() {

   const int maxInput = 100;
   int i;
   double number, average, sum = 0.0;

   for (i = 1; i <= maxInput; ++i) {
      printf("%d. Enter a number: ", i);
      scanf("%lf", &number);
      
      // go to jump if the user enters a negative number
      if (number < 0.0) {
         goto jump;
      }
      sum += number;
   }

jump:
   average = sum / (i - 1);
   printf("Sum = %.2f\n", sum);
   printf("Average = %.2f", average);

   return 0;
}

Kết quả :

1. Enter a number: 3
2. Enter a number: 4.3
3. Enter a number: 9.3
4. Enter a number: -2.9
Sum = 16.60
Average = 5.53

2. Ưu điểm của câu lệnh goto

2.1. Đơn giản và dễ hiểu

Trong một số trường hợp, việc sử dụng câu lệnh goto có thể giúp rõ ràng và đơn giản hóa source code. Nhưng nó chỉ đơn giản khi source code của bạn ít.

2.2. Được sử dụng trong việc thoát khỏi vòng lặp lồng nhau:

Goto có thể được sử dụng để thoát khỏi nhiều vòng lặp lồng nhau một cách dễ dàng và hiệu quả.

Ví dụ :

#include <stdio.h>

int main() {
    int i, j;

    for (i = 1; i <= 3; i++) {
        printf("Vòng lặp ngoài i = %d\n", i);

        for (j = 1; j <= 3; j++) {
            printf("Vòng lặp trong j = %d\n", j);
            
            if (i == 2 && j == 2) {
                goto endLoop; // Thoát khỏi cả hai vòng lặp ngoài và trong
            }
        }
    }

    endLoop:
    printf("Thoát khỏi vòng lặp lồng nhau!");

    return 0;
}

Trong ví dụ này, chúng ta có hai vòng lặp lồng nhau: vòng lặp ngoài với biến i và vòng lặp trong với biến j. Chúng ta muốn thoát khỏi cả hai vòng lặp khi ij đạt giá trị 2.

Bằng cách sử dụng câu lệnh goto và label endLoop, chúng ta có thể dễ dàng thoát khỏi vòng lặp lồng nhau khi ij đạt giá trị mong muốn. Khi chương trình chạy tới điểm label endLoop, nó sẽ tiếp tục thực hiện các câu lệnh sau đó.

Kết quả :

Vòng lặp ngoài i = 1
Vòng lặp trong j = 1
Vòng lặp trong j = 2
Vòng lặp trong j = 3
Vòng lặp ngoài i = 2
Vòng lặp trong j = 1
Vòng lặp trong j = 2
Thoát khỏi vòng lặp lồng nhau!

2.3. Xử lý các tình huống đặc biệt

Goto cung cấp một phương pháp thoát khỏi các tình huống bất thường hoặc xử lý các lỗi ngoại lệ.

Ví dụ :

#include <stdio.h>

int main() {
    int a = 0;
    int b = 42;
    int result;

    if (a == 0) {
        printf("Lỗi: Chia cho 0 không hợp lệ!\n");
        goto error; // Nhảy tới điểm xử lý lỗi
    }

    result = b / a;
    printf("Kết quả: %d\n", result);

    return 0;

    error:
    printf("Xảy ra lỗi. Không thể tính toán kết quả!\n");
    return -1;
}

Trong ví dụ này, chúng ta muốn kiểm tra xem biến a có bằng 0 hay không trước khi thực hiện phép chia b / a. Nếu a bằng 0, ta sẽ in ra một thông báo lỗi và thoát khỏi chương trình.

Bằng cách sử dụng câu lệnh goto và label error, chúng ta có thể dễ dàng nhảy tới điểm xử lý lỗi và thực hiện các câu lệnh xử lý lỗi phù hợp. Sau đó, chúng ta có thể thoát khỏi chương trình hoặc thực hiện các tác vụ khác, tuỳ thuộc vào logic cụ thể của chương trình.

Kết quả :

Lỗi: Chia cho 0 không hợp lệ!
Xảy ra lỗi. Không thể tính toán kết quả!

Lưu ý rằng việc sử dụng câu lệnh goto trong lập trình C có thể làm source code trở nên khó hiểu hơn và khó bảo trì. Do đó, cần sử dụng cẩn thận và chỉ khi không có cách khác để giải quyết vấn đề thì ta mới dùng.

3. Nhược điểm của câu lệnh goto.

Cái gì cũng có 2 mặt, có lợi thì sẽ có hại, có ưu điểm thì cũng sẽ có nhược điểm. Việc sử dụng câu lệnh goto cũng có điểm yếu và hạn chế sau.

3.1. Khó hiểu và khó bảo trì:

Sử dụng goto có thể làm cho mã nguồn trở nên khó hiểu hơn, đặc biệt là khi sử dụng goto để nhảy tới các vị trí không liên quan trong source code. Điều này có thể làm hạn chế khả năng bảo trì và debug source code.

3.2. Rối loạn luồng điều khiển:

Sử dụng goto có thể làm cho luồng điều khiển của chương trình trở nên rối loạn và khó dự đoán. Việc nhảy tới các vị trí ngẫu nhiên trong mã nguồn có thể gây ra những vấn đề phức tạp và khó tìm ra lỗi.

3.3. Có thể dẫn đến lỗi logic

Sử dụng goto một cách không cẩn thận có thể dẫn đến lỗi logic trong chương trình. Nhảy qua các đoạn mã quan trọng hoặc bỏ qua các kiểm tra điều kiện có thể gây ra lỗi không mong muốn và khó tìm ra.

3.4. Không linh hoạt

Sử dụng goto giới hạn khả năng mở rộng và tái sử dụng mã nguồn. Code sử dụng goto thường khó tái sử dụng và khó thay đổi để phù hợp với yêu cầu mới.

4. Kết luận

Câu lệnh goto trong lập trình C có những hạn chế rõ ràng. Tuy nhiên, nếu được sử dụng một cách cân nhắc và cẩn thận, nó vẫn có thể giúp giải quyết một số vấn đề cụ thể. Quan trọng nhất là hiểu rõ nhược điểm của nó và hạn chế việc sử dụng goto trong mã nguồn quy mô lớn.

Khi không có cách nào khác để giải quyết vấn đề một cách tốt hơn. Và nếu dùng câu lệnh goto có thể giải quyết được vấn đề bài toán tốt hơn thì ta nên dùng.

Trong các dự án mà chúng ta có nhiều developer (team work) thì nên sử dụng các cấu trúc điều khiển khác như if-else, switch-case, và vòng lặp làm cho mã nguồn dễ đọc và bảo trì hơn.

Trên đây là những ý kiến và hiểu biết cá nhân. Các bạn có đóng góp hoặc feedback gì thêm cho bài viết được tốt hơn thì vui lòng comment bên dưới nhé.

Chúc các bạn học tập tốt.

Nguồn tham khảo :

  1. https://www.programiz.com/c-programming/c-goto-statement
  2. https://www.tutorialspoint.com/cprogramming/c_goto_statement.htm

1 bình luận trong “Bài 11 : Lệnh goto trong lập trình C”

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *