How can I use a "goto" statement to break out of a loop
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] ;
//break;
}
}
}
I wanted to keep the values at which i and j were when I left the nested for loop. How can I use a goto statement for that?
@MatheusRocha Yes, it does. In fact, C++ has special rules about goto that prevent programmers from making improper jumps, e.g. jumping over initialization.
Using break in a nested loop In a nested loop, a break statement only stops the loop it is placed in. Therefore, if a break is placed in the inner loop, the outer loop still continues. However, if the break is placed in the outer loop, all of the looping stops.
This article demonstrates that local goto statements create RAII for C code. The code is neat an easy to follow. Imagine that as a series of nested if statements. I understand that goto is taboo in many other languages because their exists other control mechanisms like try/catch etc, however, in C it seems appropriate.
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 goto
s 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
}
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With