Thread: what is goto?

  1. #1
    Registered User
    Join Date
    Dec 2019
    Posts
    17

    what is goto?

    What exactly is the term goto and where is it used?

    How can I delete goto from this code?

    Thanks...

    Code:
    
    
    #include <stdio.h>
    
    
    #define INF (0x7FFFFFFF)
    
    
    #define size1 (10)
    #define size2 (10)
    
    
    #define verbose (1)
    
    
    int Array[size1][size2] = { {62,77,39,77,23,1,70,65,41,18}, { 72,36,37,63,26,83,46,2,12,6 },{ 71,18,86,7,75,21,90,18,88,35 },
    { 6,52,10,68,74,77,98,11,9,88 }, { 19,55,99,17,87,4,46,43,39,66 } ,{ 48,18,90,44,63,35,65,92,37,18 } ,
    { 81,12,29,61,39,76,5,86,27,31 },{ 85,18,86,51,49,96,38,83,52,7 },{ 48,11,60,83,74,88,43,95,30,96 },{12,47,37,3,2,91,19,90,41,83 } };
    char Result[size1][size2]= {'0'};  // used as boolean
    
    
    void initArray()
    {
        int i, j;
    
    
        for (i = 0;i < size1;++i){
            for (j = 0;j < size2;++j) {
                printf("%d\t", Array[i][j]);
            }
            printf("\n");
        }
    }
    
    
    void hungarian()
    {
        int i, j;
        int false = 0, true = 1;
    
    
        unsigned int m = size1, n = size2;
        int k;
        int l;
        int s;
        int col_mate[size1] = { 0 };
        int row_mate[size2] = { 0 };
        int parent_row[size2] = { 0 };
        int unchosen_row[size1] = { 0 };
        int t;
        int q;
        int row_dec[size1] = { 0 };
        int col_inc[size2] = { 0 };
        int slack[size2] = { 0 };
        int slack_row[size2] = { 0 };
        int unmatched;
        int cost = 0;
    
    
        //printf("Using heuristic\n");
        for (l = 0;l < n;l++)
        {
            s = Array[0][l];
            for (k = 1;k < n;k++)
                if (Array[k][l] < s)
                    s = Array[k][l];
            cost += s;
            if (s != 0)
                for (k = 0;k < n;k++)
                    Array[k][l] -= s;
        }
        
    
    
        
        t = 0;
        for (l = 0;l < n;l++)
        {
            row_mate[l] = -1;
            parent_row[l] = -1;
            col_inc[l] = 0;
            slack[l] = INF;
        }
        
        for (k = 0;k < m;k++)
        {
            s = Array[k][0];
            for (l = 1;l < n;l++)
                if (Array[k][l] < s)
                    s = Array[k][l];
            row_dec[k] = s;
            for (l = 0;l < n;l++)
                if (s == Array[k][l] && row_mate[l] < 0)
                {
                    col_mate[k] = l;
                    row_mate[l] = k;
                    if (verbose)
                                goto row_done;
                }
            col_mate[k] = -1;
            if (verbose)
                printf("node %d: unmatched row %d\n", t, k);
            unchosen_row[t++] = k;
        row_done:
            ;
        }
    
    
        if (t == 0)
            goto done;
        unmatched = t;
        while (1)
        {
            if (verbose)
                printf("Matched %d rows.\n", m - t);
            q = 0;
            while (1)
            {
                while (q < t)
                {
                    
                    {
                        k = unchosen_row[q];
                        s = row_dec[k];
                        for (l = 0;l < n;l++)
                            if (slack[l])
                            {
                                int del;
                                del = Array[k][l] - s + col_inc[l];
                                if (del < slack[l])
                                {
                                    if (del == 0)
                                    {
                                        if (row_mate[l] < 0)
                                            goto breakthru;
                                        slack[l] = 0;
                                        parent_row[l] = k;
                                        if (verbose)
                                            printf("node %d: row %d==col %d--row %d\n",
                                                t, row_mate[l], l, k);
                                        unchosen_row[t++] = row_mate[l];
                                    }
                                    else
                                    {
                                        slack[l] = del;
                                        slack_row[l] = k;
                                    }
                                }
                            }
                    }
                    
                    q++;
                }
    
    
                
                s = INF;
                for (l = 0;l < n;l++)
                    if (slack[l] && slack[l] < s)
                        s = slack[l];
                for (q = 0;q < t;q++)
                    row_dec[unchosen_row[q]] += s;
                for (l = 0;l < n;l++)
                    if (slack[l])
                    {
                        slack[l] -= s;
                        if (slack[l] == 0)
                        {
                            
                            k = slack_row[l];
                            if (verbose)
                                printf(
                                    "Decreasing uncovered elements by %d produces zero at [%d,%d]\n",
                                    s, k, l);
                            if (row_mate[l] < 0)
                            {
                                for (j = l + 1;j < n;j++)
                                    if (slack[j] == 0)
                                        col_inc[j] += s;
                                goto breakthru;
                            }
                            else
                            {
                                parent_row[l] = k;
                                if (verbose)
                                    printf("node %d: row %d==col %d--row %d\n", t, row_mate[l], l, k);
                                unchosen_row[t++] = row_mate[l];
                            }
                            // End look at a new zero 22
                        }
                    }
                    else
                        col_inc[l] += s;
                
            }
        breakthru:
            
            if (verbose)
                printf("Breakthrough at node %d of %d!\n", q, t);
            while (1)
            {
                j = col_mate[k];
                col_mate[k] = l;
                row_mate[l] = k;
                if (verbose)
                    printf("rematching col %d==row %d\n", l, k);
                if (j < 0)
                    break;
                k = parent_row[j];
                l = j;
            }
            
            if (--unmatched == 0)
                goto done;
            
            t = 0;
            for (l = 0;l < n;l++)
            {
                parent_row[l] = -1;
                slack[l] = INF;
            }
            for (k = 0;k < m;k++)
                if (col_mate[k] < 0)
                {
                    if (verbose)
                    
                    unchosen_row[t++] = k;
                }
            
        }
    done:
    
    
        for (i = 0;i < m;i++)
            cost += row_dec[i];
        for (i = 0;i < n;i++)
            cost -= col_inc[i];
        printf("Cost is %d\n", cost);
    }
    
    
    main()
    {
        int y, x, i;
    
    
        initArray();
        hungarian();
    
    
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > How can I delete goto from this code?
    Delete all of it.

    200 lines of multiple nested loops, poor variable names, global variables, no comments - it's awful.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Sometimes goto is useful as shown in the threads linked to below. The first is about a 4 way merge sort that doesn't use a min-heap. The second is a more generic question. Typically goto is useful when multiple code paths branch to a common destination point. A simple example is when any of the paths detects a condition that prevents the program from running and going to a common exit point. In the case of my 4 way merge example, there are multiple paths leading to each of the 4 cases that represent the sorted run with the current smallest element. The replies show an alternative that replaces the common destination point with multiple instances of function calls, in this case making the code more difficult to read (as you have to back track to see those functions), and somewhat slower.

    Another common argument is that other than conditional move instructions, compiled code is typically going to end up with "gotos" (unconditional jumps) anyway, to handle if/else and switch/case statements. In the case of Microsoft Masm 6.0 and later assembler, there are directives for if/else, do/while, ..., that eliminate the need to use labels, but "gotos" (unconditional jumps) are still being generated.

    As pointed out in the second thread, C# checks for goto's that could branch into code that results in using uninitialized variables. There's no reason a C/C++ or other language compiler could not also implement the same check (some C/C++ compilers may already be doing this).

    Sometimes "goto" is useful

    https://softwareengineering.stackexchange.com/questions/566
    Last edited by rcgldr; 04-29-2020 at 08:47 PM.

  4. #4
    Registered User
    Join Date
    Nov 2018
    Location
    Amberg in upper palatinate, Bavaria
    Posts
    66
    Hallo muhammetekurt!

    Salem is right, this code is terrible.
    The only way to delete goto is to swap out some code to functions:
    Like to change your example to this:

    first hungarian.h:
    Code:
    #ifndef HUNGARIAN_INC_
    #define HUNGARIAN_INC_
    
    #include <stdio.h>
    #include <limits.h> 
     
    
    #define size1 (10)
    #define size2 (10)
    #define verbose (1)
    
    
    
    void initLoop(int (*array)[10], int limit, int initvalue);
    int hungi(void);
     
    class hungarian{
    
    public:
       hungarian();
       ~hungarian();
        int m;
        int n;
        int Array[size1][size2];
        int unmatched;
        int cost = 0;
        int del;
        int i,j, l, k, s, t, q; 
        int col_mate[size1] = { 0 };
        int row_mate[size2] = { 0 };
        int parent_row[size2] = { 0 };
        int unchosen_row[size1] = { 0 };
        int row_dec[size1] = { 0 };
        int col_inc[size2] = { 0 };
        int slack[size2] = { 0 };
        int slack_row[size2] = { 0 };
           
        void ShowArray(void);
        int hungi(void);
        int durchbruch(void);   
        void done(void);
        void SetArrays(void);
        void SetArraysb(void);
        int Schleife_a(void);
        int Schleife_b(void);
        void SetArraysc(void);
        int SetArraysd(void);
        
    }; 
      
    #endif

    now hungarian.cpp

    Code:
    #include "hungarian.h"
    
    hungarian::hungarian()
    {
     int i, j;
     
     int xArray[size1][size2] = { 
        { 62,77,39,77,23,1,70,65,41,18 }, 
        { 72,36,37,63,26,83,46,2,12,6 },
        { 71,18,86,7,75,21,90,18,88,35 },
        { 6,52,10,68,74,77,98,11,9,88 }, 
        { 19,55,99,17,87,4,46,43,39,66 },
        { 48,18,90,44,63,35,65,92,37,18 },
        { 81,12,29,61,39,76,5,86,27,31 },
        { 85,18,86,51,49,96,38,83,52,7 },
        { 48,11,60,83,74,88,43,95,30,96 },
        { 12,47,37,3,2,91,19,90,41,83 } };
     
     
     
        for (i = 0;i < size1;++i)
            for (j = 0;j < size2;++j) {
             Array[i][j] = xArray[i][j];
            }
       
      m = size1;
      n = size2; 
    
    }
    
    hungarian::~hungarian()
    {
        
    }
    
    void hungarian::ShowArray(void)
    {
        int i, j;
     
     
        for (i = 0;i < size1;++i){
            for (j = 0;j < size2;++j) {
                printf("%02d\t", Array[i][j]);
            }
            printf("\n");
        }
    }
    
    
    void hungarian::done(void)
    { 
        
        for (i = 0;i < m;i++)  cost += row_dec[i];
        for (i = 0;i < n;i++)  cost -= col_inc[i];
        printf("Cost is %d\n", cost);
    }
    
    void initLoop(int (*array)[10], int limit, int initvalue)
    {
     int l;
     
       for (l = 0;l < limit;l++)  
         (*array)[l] = initvalue;    
    } 
    
     
    int hungarian::hungi(void)
    {
      int rewer = 0, sleib = 1;  
        //int falsch, wahr;
     
        //falsch = 0;
        //wahr = 1;
     
         //printf("Using heuristic\n");
        
        SetArrays();
    
        if (t == 0)
         {
          done();
          return rewer;    
         }  
        unmatched = t;
        while (1)
         {
            if (verbose)
                printf("Matched %d rows.\n", m - t);
            q = 0;
            sleib = 1;
            do
            {
                 do
                 {
                   if((Schleife_b()) == 0) {sleib = 0; break;}
                    q++;
                 } while (q < t);
                 
                 if(sleib == 0) break;
                 
                 SetArraysb();
                 if((Schleife_a()) == 0) break; 
            
              }while (sleib != 0);
      
                if((durchbruch()) == 0)
                 return rewer;
          }
      
       done();
    
     return rewer;
    }
    
    int hungarian::durchbruch(void)
     {
      int rewer = -1;
             
            if (verbose)
                printf("Breakthrough at node %d of %d!\n", q, t); 
             
             while (1)
            {
                j = col_mate[k];
                col_mate[k] = l;
                row_mate[l] = k;
                if (verbose)
                    printf("rematching col %d==row %d\n", l, k);
                if (j < 0)
                    break;
                k = parent_row[j];
                l = j;
            }
             
             --unmatched;
    
             if (unmatched == 0)
             {
              done();
              rewer = 0;
              return rewer;    
             }  
             
             t = 0;
            
            initLoop(&parent_row, n, -1);
            initLoop(&slack, n, INT_MAX);
    
           
            for (k = 0; k < m; k++)
                if (col_mate[k] < 0)
                {
                    if (verbose)
                    
                    unchosen_row[t++] = k;
                }
             
      return rewer;
        }    
        
        
    void hungarian::SetArrays(void)
    {
        for (l = 0; l < n; l++)
        {
            s = Array[0][l];
            for (k = 1;k < n;k++)
                if (Array[k][l] < s)
                    s = Array[k][l];
            cost += s;
            if (s != 0)
                for (k = 0;k < n;k++)
                    Array[k][l] -= s;
        }
         
          
        t = 0;
        
        for (l = 0;l < n;l++)
        {
            row_mate[l] = -1;
            parent_row[l] = -1;
            col_inc[l] = 0;
            slack[l] = INT_MAX;
        }
        
    
        for (k = 0;k < m;k++)
        {
          SetArraysc();
          if((SetArraysd()) != 0)
           {
            col_mate[k] = -1;
            if (verbose) printf("node %d: unmatched row %d\n", t, k);
             unchosen_row[t++] = k;
           }    
        }    
        
    }      
    
    void hungarian::SetArraysb(void)
    {             
                s = INT_MAX;
                for (l = 0;l < n;l++)
                    if (slack[l] && slack[l] < s)
                        s = slack[l];
                for (q = 0;q < t;q++)
                    row_dec[unchosen_row[q]] += s;
                    
    }
    
    int hungarian::Schleife_a(void) 
    {
       int rewer = -1;   
    
            for (l = 0;l < n;l++)
                    if (slack[l])
                    {
                        slack[l] -= s;
                        if (slack[l] == 0)
                        {
                             
                            k = slack_row[l];
                            if (verbose)
                                printf(
                                    "Decreasing uncovered elements by %d produces zero at [%d,%d]\n",
                                    s, k, l);
                            if (row_mate[l] < 0)
                            {
                                for (j = l + 1;j < n;j++)
                                    if (slack[j] == 0)
                                        col_inc[j] += s;
                                
                                return 0;
                                
                            }
                            else
                            {
                                parent_row[l] = k;
                                if (verbose)
                                    printf("node %d: row %d==col %d--row %d\n", t, row_mate[l], l, k);
                                unchosen_row[t++] = row_mate[l];
                            }
                            // End look at a new zero 22
                        }
                    }
                    else
                        col_inc[l] += s;
         
          return rewer;
    }   
    
    int hungarian::Schleife_b(void)
    {
     int rewer = -1;
    
                       k = unchosen_row[q];
                        s = row_dec[k];
     
                        for (l = 0;l < n;l++)
                            if (slack[l])
                            {
                                del = Array[k][l] - s + col_inc[l];
                                if (del < slack[l])
                                {
                                    if (del == 0)
                                    {
                                        if (row_mate[l] < 0)
                                         {
                                          return 0;
                                         }
                                        slack[l] = 0;
                                        parent_row[l] = k;
                                        if (verbose)
                                            printf("node %d: row %d==col %d--row %d\n",
                                                t, row_mate[l], l, k);
                                        unchosen_row[t++] = row_mate[l];
                                    }
                                    else
                                    {
                                        slack[l] = del;
                                        slack_row[l] = k;
                                    }
                                }
                            }
                            
                            
    return rewer;
    }
    
    void hungarian::SetArraysc(void)
    { 
       s = Array[k][0];
    
            for (l = 1;l < n;l++)
                if (Array[k][l] < s)
                    s = Array[k][l];
            row_dec[k] = s;
    }    
    
    int hungarian::SetArraysd(void)
    {        
     int rewer = -1; 
           for (l = 0;l < n;l++)
                if (s == Array[k][l] && row_mate[l] < 0)
                 {
                  col_mate[k] = l;
                  row_mate[l] = k;
                  rewer = 0;
                  return rewer;
                 }
     return rewer;
    }
    at last main.cpp:
    Code:
    #include "hungarian.h"
    
     
    
    char Result[size1][size2]= {'0'};  // used as boolean
     
    
     
    int main(int argc, char **argv)
    {
       hungarian hug; 
        
        printf("Init Arrays\n");
        hug.ShowArray();
        printf("Init Arrays ready\n");
        hug.hungi();
     
     return 0;
    }
    I know, it hurts to use printf in stead of cout in c++, but i think it is no Problem
    for this example.
    output here:
    Code:
    Init Arrays
    62      77      39      77      23      01      70      65      41      18
    72      36      37      63      26      83      46      02      12      06
    71      18      86      07      75      21      90      18      88      35
    06      52      10      68      74      77      98      11      09      88
    19      55      99      17      87      04      46      43      39      66
    48      18      90      44      63      35      65      92      37      18
    81      12      29      61      39      76      05      86      27      31
    85      18      86      51      49      96      38      83      52      07
    48      11      60      83      74      88      43      95      30      96
    12      47      37      03      02      91      19      90      41      83
    Init Arrays ready
    node 0: unmatched row 4
    node 1: unmatched row 8
    Matched 8 rows.
    node 2: row 0==col 5--row 4
    node 3: row 5==col 1--row 8
    Decreasing uncovered elements by 5 produces zero at [5,9]
    node 4: row 7==col 9--row 5
    Decreasing uncovered elements by 5 produces zero at [4,0]
    node 5: row 3==col 0--row 4
    Breakthrough at node 5 of 6!
    rematching col 2==row 3
    rematching col 0==row 4
    Matched 9 rows.
    node 1: row 5==col 1--row 8
    node 2: row 7==col 9--row 5
    Decreasing uncovered elements by 11 produces zero at [8,8]
    Breakthrough at node 3 of 3!
    rematching col 8==row 8
    Cost is 101
    Sorry for some german words, like 'durchbruch' instead of 'breakthru'

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. goto
    By R.Stiltskin in forum C++ Programming
    Replies: 33
    Last Post: 12-30-2009, 07:23 PM
  2. goto help?
    By Zenomori in forum C++ Programming
    Replies: 5
    Last Post: 05-03-2005, 03:54 PM
  3. goto
    By volk in forum C++ Programming
    Replies: 6
    Last Post: 04-23-2003, 10:04 PM
  4. Someone used a goto...
    By adrianxw in forum A Brief History of Cprogramming.com
    Replies: 23
    Last Post: 01-30-2003, 02:43 AM
  5. Why is goto so bad?
    By Munkey01 in forum C++ Programming
    Replies: 14
    Last Post: 01-02-2003, 07:11 PM

Tags for this Thread