How to use goto to break a nested loop

风流意气都作罢 提交于 2019-12-04 10:51:05

Like this:

int i,j;
for(i = 0; i < 9; i++)
{
    for(j = 0; j < 9; j++)
    {
        //cout << " " << Matrix[i][j];
        //cout << "i: " << i << endl;
        if(Matrix[i][j] == 0)
        {
            //temp = 10;
            goto end;
            //break;
        }
    }
}
end:
cout << i << " " << j << endl;

Just as you use goto in any other situation. As long as you don't cross scopes with local variables in them, you can actually think of it as "goto this and that line":

for (/* ... */) {
  /* ... */
  if (/* ... */)
    goto finalise;
}
finalise:
  foo = bar; //...

However, there are many situations when goto is an indicator for not well designed code. By no means always, but often.

I suggest you use gotos big brother return and factor out your code into a function:

inline std::pair<int,int> findZeroEntry(std::vector matrix) {
  for (int i = 0; i < 9; i++)
    for (int j = 0; j < 9; j++)
      if (Matrix[i][j] == 0)
        return std::make_pair(i,j);
  return std::make_pair(9,9); // error
}
Cheers and hth. - Alf

Well, @bitmask's answer has already said most of what I thought of saying when I read the question.

But for completeness, here's another technique:

Matrix              m;
Index2D< 9, 9 >     pos;

for( ; pos < pos.end();  ++pos )
{
    if( m( pos.x(), pos.y() ) == 0 )
    {
        break;
    }
}
cout << pos.x() << " " << pos.y() << endl;

IMHO this is far more clear code.

Also, the matrix can then be made to support indexing via Index2D values, thus reducing the above to just …

Matrix              m;
Index2D< 9, 9 >     pos;

for( ; pos < pos.end();  ++pos )
{
    if( m[pos] == 0 )
    {
        break;
    }
}
cout << pos.x() << " " << pos.y() << endl;

Since there’s nothing like Index2D in the standard library, it needs to be defined somewhere, e.g. like

template< int width, int height >
struct Index2D
{
    int         i_;

    int x() const { return i_ % width; }
    int y() const { return i_ / width; }

    void operator++() { ++i_; }

    bool operator<( Index2D const& other ) const
    {
        return (i_ < other.i_);
    }

    Index2D(): i_( 0 ) {}

    Index2D( int const x, int const y )
        : i_( width*y + x )
    {}

    static const Index2D endValue;
    static Index2D end() { return endValue; }
};

template< int width, int height >
Index2D< width, height > const Index2D< width, height >::endValue( 0, height );

But then it can be reused everywhere that you need this functionality.

You don't need goto to leave the nested for loop and save off those variables. Merely, you want to break out of each loop successively. Just have a boolean at the appropriate scope level that you check to know if need to break out of the loops.

Corrected example

IE:

bool HasFoundZero = false;
for(i = 0; i < 9; i++)
{
    for(j = 0; j < 9; j++)
    {
        //cout << " " << Matrix[i][j];
        //cout << "i: " << i << endl;
        if(Matrix[i][j] == 0)
        {
            //temp = 10;
                HasFoundZero = true;
        }
        if(HasFoundZero)
        {
            break;
        }
    }
    if(HasFoundZero)
    {
        break;
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!