C/C++: Có nên xài "goto" hay không?

Tình hình là em thắc mắc mình có nên sử dụng goto hay ko, em có 1 bài là tổng hợp rất nhiều bài tập đã làm thành một menu sử dụng switch case, có thể gồm nhiều switch trong case chính.
(nghĩa là trong menu chính có các lệnh case như case 1:. khi vào case 1 thì nó lại gồm 1 menu khác). Em có viết được hàm quay lại menu chính nhưng ko gộp vào được khi 2 switch case, xưa giờ e nghe nói ko nên sử dụng goto, nhưng hôm nay e test thì khá là tiện để làm bài của em.
Em hỏi có nên lạm dụng nó ko?

p/s: Nếu ko nên thì có thể giúp e thuật toán 1 hàm thoát khỏi menu phụ và quay về menu chính.
Dạng như. Mở console là có Menu1 -> case 1-> menu 2-> case 1-> menu 3. rồi thiết lập số 0-> Quay về menu 2. SỐ 0 ở menu 2-> quay về menu 1.
Em cám ơn.

1 Like

Nếu mình biết cách quản lý thì có thể sử dụng goto, goto có thể được dùng trong một số trường hợp. Trong video này có giới thiệu: Video Ngôn Ngữ C - 21 - Lệnh goto

Trí share code lên xem thử?

Đây nha anh, em mới chỉ test thôi ạ, còn phần bài tập kia e ms chỉ thiết lập các bài tập cũ. Nên em test thử cái này thôi ạ!

#include <stdlib.h>
#include <stdio.h>
#include <conio.h>

void QuayLai()
{
    printf("Press Enter back to menu");
    while (true)
    {
        fflush(stdin);
        char cPressKey;
        scanf("%c", &cPressKey);
        if (cPressKey==10)
        {
            break;
        }
        else
        {
            continue;
        }
    }
}

void main()
{
    
    while (true)
    {
        MenuChinh:
        system("cls");
        // ========================================Ghi ra các thao tác trên mảng
        printf("\n\n1,Test (Menu 1)\n");
        printf("2, Test menu \n");
        printf(" -- Input your choice -- : ");
        //=========================================Nhập vào chức năng chương trình
        
        while (true)
        {
            //Đọc phím chức năng
            int iCase;
            scanf("%d", &iCase);
            // Chọn chức năng
            switch (iCase)
            {
            case 0: //====================================================CASE 0
            {
                      return;
                      break;
            }
            case 1: //====================================================CASE 1
            {
                      system("cls");
                      while (true)
                    {
                    system("cls");
                    // ========================================Ghi ra các thao tác trên mảng
                    printf("\n\n1, Test (menu 2)\n");
                    printf("2, Test menu\n");
                    printf(" -- Input your choice -- : ");
                    //=========================================Nhập vào chức năng chương trình
        
                    while (true)
                    {
                        //Đọc phím chức năng
                        int iCase;
                        scanf("%d", &iCase);
                        // Chọn chức năng
                        switch (iCase)
                        {
                        case 0: //====================================================CASE 0
                        {
                            goto MenuChinh;
                                  
                        }
                                    case 1: //====================================================CASE 1
                                    {
                                              system("cls");
                                              printf("Test menu 1 1\n");
                                              break;
                                    }
                                    case 2: //====================================================CASE 2
                                    {
                                              system("cls");
                                                printf("Test menu 2 2\n");
                                                break;
                                    }
                                    default: //===================================================KHÔNG HỢP LỆ
                                    {
                                            system("cls");
                                            printf("\t\t Input again! Your input fail!!!        \n");
                                            break;
                                    }
                                    }

                                    if (iCase>=0 && iCase<99)
                                    {
                                        break;
                                    }    
                                    }
                                QuayLai();
                            }
                     
                     break;
            }
            case 2: //====================================================CASE 2
            {
                      system("cls");
                      printf("Test menu\n");
                      break;
            }
            default: //===================================================KHÔNG HỢP LỆ
            {
                    system("cls");
                    printf("\t\t Input again! Your input fail!!!        \n");
                    break;
            }
            }

            if (iCase>=0 && iCase<99)
            {
                break;
            }    
            }
        QuayLai();
    }
}

Với lại đây là e thử sử dụng với goto.

Code này dở lắm, đừng code kiểu này. Tách ra làm nhiều hàm con đi. Coi đoạn code nào có thể gom lại thành hàm thì mình gom lại cho ngắn.

Em chỉ test thôi. còn lúc viết thì em sẽ nhét vào hàm con mà. :smiley:
Chủ yếu là cái phần goto thôi ấy anh!

Em sửa lại code đi, sau khi nhìn lại xem thử code gọn hơn. Mình sẽ quyết định có sử dụng goto hay không dễ hơn.

Anh nghĩ sử dụng goto hợp lý thì không vấn đề gì cả.

ok em cám ơn! :D. nếu bất đắc dĩ thì e sẽ dùng, còn ko em sẽ cố viết cái code khác.

not really, đôi khi dùng goto lại làm code dễ đọc hơn. Không phải là bất đắc dĩ đâu :slight_smile: Trong video của anh có giới thiệu 1-2 ví dụ gì đấy. Trong sách Code Complete 2 có nói đầy đủ cách dùng.

Như trong đoạn code nhỏ dưới đây, mình dùng goto để quay về nhập lại ID khi ID đã tồn tại. Nếu thay thành vòng lặp thì thành ra lại phức tạp hơn nhiều. Thế nên cảm thấy tiện lợi hơn thì cứ làm thôi.

void addLecturer(Faculty& F)  {

    label: //Đặt label ở đây
    system("cls");
    Lecturer L;
    L.createID();

    if(checkExist(L.getID(),F)) {

        cout << "This id number is exist. Please enter id again!" << endl;
        system("pause");
        goto label; //Chuyển về label ở đây
    }
    else    {

        L.createName();
        L.createMajor();
        L.createQualification();
        L.createPosition();

        F.addLecturer(L);
        updateFile(F);
    }
    system("pause");
}
3 Likes

Mình đã dùng cách khác được rồi nhé. Cám ơn anh chi em nhiều :smiley:

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?