Как использовать goto, чтобы разорвать вложенный цикл

Как я могу использовать оператор «goto», чтобы выйти из цикла

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 и j, когда я покинул вложенный цикл for. Как я могу использовать оператор goto для этого?

3

Решение

Как это:

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;
9

Другие решения

Так же, как вы используете goto в любой другой ситуации. Пока вы не пересекаете области видимости с локальными переменными в них, вы можете думать об этом как о «переходе к этой и той строке»:

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

Однако есть много ситуаций, когда goto является индикатором плохо разработанного кода. Далеко не всегда, но часто.

Я предлагаю вам использовать gotoбольшой брат return и выделите ваш код в функцию:

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
}
5

Что ж, @ bitmask’s answer уже сказал большинство из того, что я думал сказать, когда я прочитал вопрос.

Но для полноты вот еще один метод:

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;

ИМХО, это гораздо более понятный код.

Кроме того, матрица может быть создана для поддержки индексации через Index2D значения, тем самым сводя вышеупомянутое к просто …

Matrix              m;
Index2D< 9, 9 >     pos;

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

Так как нет ничего подобного Index2D в стандартной библиотеке его нужно где-то определить, например, лайк

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 );

Но тогда он может быть использован везде, где вам нужна эта функциональность.

2

Вам не нужно goto оставить вложенный цикл и сохранить эти переменные. Просто вы хотите вырваться из каждой петли подряд. Просто имейте логическое значение на соответствующем уровне контекста, который вы проверяете, чтобы знать, нужно ли выходить из циклов.

Исправленный пример

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;
}
}
2
По вопросам рекламы [email protected]