Выход из двух циклов сразу (без goto)
Здрасти, как можно выйти из нескольких циклов сразу? без goto.
1 2 3 4 5
for (int i=0; iROWS; i++) for (int j=0; jCOLS; j++){ if (mas[i][j]==0) //то выход из обоих циклов std::cout[ i][j]; }
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Выход из двух циклов for
Как можно выйти из двух циклов for ? break выйдет из второго цикла, а exit из процедуры. Можно.
Превращение кода с goto в код без goto
Помогите переписать это код без goto и потери производительности.А то мне кажется написано.
Сравнение двух массивов без вложенных циклов
Извиняюсь, что помещаю здесь этот вопрос, я сам по идее должен был догадаться, но никак не могу.
Регистрация: 09.01.2009
Сообщений: 41
ниначмуроФ
851 / 535 / 110
Регистрация: 12.10.2009
Сообщений: 1,913
Сообщение от Mulat
return требует число, а если поставлю число (return 1) то конец программе
Регистрация: 27.01.2010
Сообщений: 63
Оператор досрочного завершения break
Пример Ex1_04. Суммирование до 10 чисел вводимой последовательности. При вводе отрицательного числа работа программы завершается.
1 2 3 4 5 6 7 8 9 10 11
#include void main() { int s=0, i, k; puts("Input up to 10 numbers."); for (i=1; i11; i++) { scanf("%d",&k); if (k0) break; s+=k; } printf("Result = %d.\n",s);
ниначмуроФ
851 / 535 / 110
Регистрация: 12.10.2009
Сообщений: 1,913
Сообщение от krolex
break — выход из одного цикла
Регистрация: 27.01.2010
Сообщений: 63
Сообщение от PointsEqual
break — выход из одного цикла
а сразу поставить второй break во внешнем цикле?)))
ниначмуроФ
851 / 535 / 110
Регистрация: 12.10.2009
Сообщений: 1,913
krolex, пример пожалуста можно?
Добавлено через 1 минуту
Сообщение от krolex
При вводе отрицательного числа работа программы завершается.
это к чему? мне же надо выход из циклов, а не завершение программы
Добавлено через 7 минут
Mulat, а код который выходит из 2-циклов с помощью return не напишеш?
12243 / 7373 / 1734
Регистрация: 25.07.2009
Сообщений: 13,522
PointsEqual, попробуй так:
1 2 3 4 5 6 7 8 9 10 11
.. for (int i=0; iROWS; i++) for (int j=0; jCOLS; j++){ if (mas[i][j]==0){ i = ROWS; break; } //то выход из обоих циклов std::cout[ i][j]; } } .
Регистрация: 27.01.2010
Сообщений: 63
прост пример,где break срабатывает при такомто условии.
ниначмуроФ
851 / 535 / 110
Регистрация: 12.10.2009
Сообщений: 1,913
easybudda, как же я сам не додумался(((
только вот так лучше
i = ROWS-1;
Добавлено через 56 секунд
Сообщение от krolex
прост пример,где break срабатывает при такомто условии.
срабатывает, но первый цикл продолжается ведь с новой итерации
12243 / 7373 / 1734
Регистрация: 25.07.2009
Сообщений: 13,522
Сообщение от PointsEqual
только вот так лучше
это чем же? по сути лишнее действие выполняется.
ниначмуроФ
851 / 535 / 110
Регистрация: 12.10.2009
Сообщений: 1,913
Сообщение от easybudda
это чем же?
i = ROWS;
ошибка выскакивает у меня
Добавлено через 7 минут
еще читал про функцию longjmp, но так и не разобрался, че она увеличивает, кому чего передает)
12243 / 7373 / 1734
Регистрация: 25.07.2009
Сообщений: 13,522
Сообщение от PointsEqual
ошибка выскакивает у меня
странно, с чего бы?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
#include #define ROWS 3 #define COLS 4 int main(void){ int m[ROWS][COLS] = { { 3, 4, 2, 1 }, { 5, 7, 0, 9 }, { 4, 2, 1, 3 } }; int i, j; for ( i = 0; i ROWS; ++i ){ for ( j = 0; j COLS; ++j ){ if ( !m[i][j] ){ i = ROWS; break; } printf("%d ", m[i][j]); } printf("\n"); } return 0; }
Единственная опасность при маргинальных случаях типа ROWS = INT_MAX но для таких лучше в качестве индексов более ёмкие типы данных использовать.
ниначмуроФ
851 / 535 / 110
Регистрация: 12.10.2009
Сообщений: 1,913
easybudda, может из за этого ?)
std::vector std::vectorint> > mas(ROWS, std::vectorint>(COLS));
а твой код, да, компилится без проблем
3550 / 2655 / 327
Регистрация: 11.03.2009
Сообщений: 6,073
Вообще это тот случай, когда goto как раз кстати. Но если дело принципа то заводишь отдельную переменную, которая будет выполнять роль флага. Если нужно прервать оба цикла из внутреннего, устанавливаешь флаг, делаешь бряк. Во внешнем цикле после внутреннего сразу проверяешь флаг, если установлен, то опять бряк.
ниначмуроФ
851 / 535 / 110
Регистрация: 12.10.2009
Сообщений: 1,913
Сообщение от kazak
я пробовал, уж очень некрасиво было, но работало)
Добавлено через 32 секунды
Сообщение от kazak
Но если дело принципа
ну да, не хочется ставить мне его
3550 / 2655 / 327
Регистрация: 11.03.2009
Сообщений: 6,073
Других вариантов нет. В неоторых случаях можно реторн применять, но только в функциях.
12243 / 7373 / 1734
Регистрация: 25.07.2009
Сообщений: 13,522
PointsEqual, всё может быть проще
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
#include #include #include #include #include #include int main(){ const int ROWS = 5; const int COLS = 10; std::srand(std::time(NULL)); std::vectorstd::vectorint> > vec(ROWS, std::vectorint>(COLS)); for ( std::vectorstd::vectorint> >::iterator i = vec.begin(); i != vec.end(); ++i ) for ( std::vectorint>::iterator j = (*i).begin(); j != (*i).end(); ++j ) *j = std::rand() % 10; std::cout <"All matrix:" :: endl; for ( std::vectorstd::vectorint> >::iterator i = vec.begin(); i != vec.end(); ++i ){ std::copy((*i).begin(), (*i).end(), std::ostream_iteratorint>(std::cout, " ")); std::cout :: endl; } std::cout <"Before zero value:" :: endl; for ( std::vectorstd::vectorint> >::iterator i = vec.begin(); i != vec.end(); ++i ){ std::vectorint>::iterator j = std::find((*i).begin(), (*i).end(), 0); std::copy((*i).begin(), j, std::ostream_iteratorint>(std::cout, " ")); std::cout :: endl; if ( j != (*i).end() ) break; } std::cout :: endl; return 0; }
ниначмуроФ
851 / 535 / 110
Регистрация: 12.10.2009
Сообщений: 1,913
easybudda, в коде ищется элемент 0, а потом если он найден коипируются все элементы до 0?
Добавлено через 2 минуты
а куда они копируются?
12243 / 7373 / 1734
Регистрация: 25.07.2009
Сообщений: 13,522
PointsEqual, не совсем так. std::find() возвращает итератор указывающий на третий параметр, или на конец списка, если его там нет. После чего в std::cout копируются разделённые пробелом элементы списка с итератора на начало списка до найденного итератора. После чего проверяется, равен ли найденный итератор итератору, указывающему на конец списка (это если элемент с нулевым значением не найден), если не равен, значит стоп-машина!
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь
Выход с циклов
Добрый день. Как можно выйти из такого цикла. Есть идея передать значение i через глобальную.
Выход из 2-ух циклов
у меня есть цикл for, а в нем еще 1 цикл for. После выхода из 1 цикла мне нужно выйти из второго.
Текстовый редактор. Выход с сохранением. Выход без сохранения.
привет! помогите, плиз: Создайте простейший текстовый редактор, в котором при выходе содержимое.
Как выйти из двух вложенных циклов
break прекращает только вложенный цикл. Внешний цикл продолжает работать. Используйте return , когда результат найден в вашем случае:
if current_user == 'ivanov': return scan_ip
Отслеживать
ответ дан 29 июл 2016 в 16:28
52.2k 11 11 золотых знаков 108 108 серебряных знаков 311 311 бронзовых знаков
Можно сделать так
while i
Вот более простой пример для понимания
for x in xrange(10): for y in xrange(10): for z in xrange(10): print x,y,z if x*y*z == 30: break # прерываем внутренний цикл else: continue # продолжаем, если внутренний цикл не был прерван break # внутренний цикл был прерван, прерываем и этот цикл else: continue break
Как выйти из всех циклов сразу c
Как это сделать?
Re: Выйти из двух циклов сразу
От: | Mish | |
Дата: | 27.05.02 10:26 | |
Оценка: | +3 -1 |
Здравствуйте LeonGorbachev, Вы писали:
LG>while(1) LG> < LG>for(int i = 0; i < 100; i++) LG> < LG>if(i == 77) LG> // вот тут хочу выйти вообще из всех циклов - из for и из while LG> > LG>> LG>
LG>Как это сделать?
Использовать goto. Ничего страшного не будет при умеренном использовании goto.
Re: Выйти из двух циклов сразу
От: | OlegO | http://www.mediachase.ru |
Дата: | 27.05.02 10:31 | |
Оценка: | -1 |
Здравствуйте LeonGorbachev, Вы писали:
LG>while(1) LG> < LG>for(int i = 0; i < 100; i++) LG> < LG>if(i == 77) LG> // вот тут хочу выйти вообще из всех циклов - из for и из while LG> > LG>> LG>
LG>Как это сделать?
Например сгенерить исключение:
try < while(1) < for(int i = 0; i < 100; i++) < if(i == 77) throw 77; > > > catch(int e) < // e==77 >
С уважением, OlegO.
Re[2]: Выйти из двух циклов сразу
Здравствуйте OlegO, Вы писали:
OO>
OO>try OO> < OO>while(1) OO> < OO>for(int i = 0; i < 100; i++) OO> < OO>if(i == 77) OO> throw 77; OO> > OO> > OO>> OO>catch(int e) OO> < OO>// e==77 OO>> OO>
Не надо так делать. Если такой код будет находиться в деструкторе, то при раскрутке стека в строке throw 77; программа будет заверешена и никакой catch (int e) не поможет.
Re[3]: Выйти из двух циклов сразу
От: | LeonGorbachev |
Дата: | 27.05.02 10:39 |
Оценка: |
Здравствуйте Mishka
MT>Не надо так делать. Если такой код будет находиться в деструкторе, то при раскрутке стека в строке throw 77; программа будет заверешена и никакой catch (int e) не поможет.
я вот как раз и не хочу через исключения. И не хочу гоу-ту.
Чего делать?
Re[4]: Выйти из двух циклов сразу
Здравствуйте LeonGorbachev, Вы писали:
LG>я вот как раз и не хочу через исключения. И не хочу гоу-ту.
LG>Чего делать?
while(1) < for(int i = 0; i < 100; i++) < if(i == 77) break; > if (i < 100) break; >
Re[5]: Выйти из двух циклов сразу
От: | Андрей | |
Дата: | 27.05.02 10:53 | |
Оценка: | 14 (2) |
Здравствуйте Mishka
MT>Здравствуйте LeonGorbachev, Вы писали:
LG>>я вот как раз и не хочу через исключения. И не хочу гоу-ту.
LG>>Чего делать?
MT>Можно так:
MT>
MT>while(1) MT> < MT>for(int i = 0; i < 100; i++) MT> < MT>if(i == 77) MT> break; MT> > MT> if (i < 100) break; MT>> MT>
Это прокатит только на VC6
Я обычно делаю так:
bool bContinue = true; while(bContinue) < for(int i = 0; i < 100; i++) < if (i == 77) < bContinue = false; break; > > >
Возможны варианты, в зависимости от контекста
Re[3]: Выйти из двух циклов сразу
От: | DarkGray | http://blog.metatech.ru/post/ogni-razrabotki.aspx |
Дата: | 27.05.02 10:56 | |
Оценка: | 6 (1) +1 -1 |
Здравствуйте Mishka
MT>Не надо так делать. Если такой код будет находиться в деструкторе, то при раскрутке стека в строке throw 77; программа будет заверешена и никакой catch (int e) не поможет.
Не пугай так народ, от и так уже запуганный.
terminate вызывается, только если второй exception не был перехвачен внутри деструктора, чего не наблюдается в данном примере.
Так что выход из вложенного цикла через исключение — нормальная ситуация.
Re[4]: return
От: | Vi2 | http://www.adem.ru |
Дата: | 27.05.02 10:57 | |
Оценка: | 1 (1) +1 -1 |
Здравствуйте LeonGorbachev, Вы писали:
LG>я вот как раз и не хочу через исключения. И не хочу гоу-ту.
LG>Чего делать?
Если есть возможность ВЫНЕСТИ эти циклы (не очень много переменных и т.д.),
можно сделать функцию и сделать возврат
. f(. ) < while(1) < for(int i = 0; i < 100; i++) < if(i == 77) // вот тут хочу выйти вообще из всех циклов - из for и из while return; > > >
Vita Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[3]: Выйти из двух циклов сразу
От: | Рек |
Дата: | 27.05.02 10:57 |
Оценка: |
Здравствуйте Mishka
MT>Здравствуйте OlegO, Вы писали:
OO>>
OO>>try OO>>< OO>> while(1) OO>> < OO>> for(int i = 0; i < 100; i++) OO>> < OO>> if(i == 77) OO>> throw 77; OO>> > OO>> > OO>>> OO>>catch(int e) OO>>< OO>> // e==77 OO>>> OO>>
MT>Не надо так делать. Если такой код будет находиться в деструкторе, то при раскрутке стека в строке throw 77; программа будет заверешена и никакой catch (int e) не поможет.
То что не надо так делать — это ты прав.
А на счет того, что программа будет завершена — не совсем.
Исключение ведь перехватывется, и из деструктора не выпускаться не будет, потому всё будет работать.
А делать так не надо, потому что исключение это дорогое средство и должны
происходить редко (так в книжках пишут), слно алгоритмы с их помощью реализовывать не нужно,
только обработку ошибок.
По мне так вариант с goto наиболее понятен, слно предпочтителен.
Если с души воротит от goto, то можно оформить внутренний цикл как функцию
и делать из неё return вместо goto.
Re[6]: Выйти из двух циклов сразу
От: | LeonGorbachev | |
Дата: | 27.05.02 11:00 | |
Оценка: | 2 (1) |
А>Я обычно делаю так:
А>
А>bool bContinue = true; А>while(bContinue) < А>for(int i = 0; i < 100; i++) < А>if (i == 77) < А>bContinue = false; А> break; А> > А> > А>> А>
Я в общем то так и делаю, только подумалось, что можно по-другому.
Re[4]: Выйти из двух циклов сразу
От: | slonnik |
Дата: | 27.05.02 11:19 |
Оценка: |
Здравствуйте DarkGray, Вы писали:
DG>Здравствуйте Mishka, Вы писали:
MT>>Не надо так делать. Если такой код будет находиться в деструкторе, то при раскрутке стека в строке throw 77; программа будет заверешена и никакой catch (int e) не поможет.
DG>Не пугай так народ, от и так уже запуганный.
DG>terminate вызывается, только если второй exception не был перехвачен внутри деструктора, чего не наблюдается в данном примере.
DG>Так что выход из вложенного цикла через исключение — нормальная ситуация.
А если не cекрет а почему именно ВТОРОЙ exception и в чем его отличие от первого
Re[6]: Выйти из двух циклов сразу
От: | Kaa | http://blog.meta.ua/users/kaa/ |
Дата: | 27.05.02 11:51 | |
Оценка: |
Здравствуйте Андрей, Вы писали:
MT>>
MT>>while(1) MT>>< MT>> for(int i = 0; i < 100; i++) MT>> < MT>> if(i == 77) MT>> break; MT>> > MT>> if (i < 100) break; MT>>> MT>>
А>Это прокатит только на VC6
Что именно? Scoping? Тогда да. А выход прокатит везде.
2 Mishka
Только это неправильное условие. Надо выйти из циклов при i == 77, а if — совсем другое условие дает (расширяет диапазон значений немеряно).
Алексей Кирдин
Re[7]: Выйти из двух циклов сразу
От: | LeonGorbachev |
Дата: | 27.05.02 12:01 |
Оценка: |
Здравствуйте Kaa, Вы писали:
Kaa>Здравствуйте Андрей, Вы писали:
А>>Это прокатит только на VC6
Kaa>Что именно? Scoping? Тогда да. А выход прокатит везде.
Что такое Scoping?
Re[4]: Выйти из двух циклов сразу
От: | Kaa | http://blog.meta.ua/users/kaa/ |
Дата: | 27.05.02 12:04 | |
Оценка: |
Здравствуйте Рек, Вы писали:
Рек>А делать так не надо, потому что исключение это дорогое средство и должны
Рек>происходить редко (так в книжках пишут), слно алгоритмы с их помощью реализовывать не нужно,
Рек>только обработку ошибок.
Есть еще способ с использованием __leave у Microsoft, и им некоторые писатели книжек пользуются, но тогда SEH надо привлекать, что часто невозможно/трудно.
Рек>Если с души воротит от goto, то можно оформить внутренний цикл как функцию
Рек>и делать из неё return вместо goto.
Стоит добавить, что для встроенной функции никакого оверхеда не будет (если она компилятору понравится, конечно), а способ самый красивый. Но с добавочной переменной типа bool — еще красивее. Не так наглядна декомпозиция алгоритма, но зато потерь в производительности не будет.
Алексей Кирдин
Re[8]: Выйти из двух циклов сразу
От: | Kaa | http://blog.meta.ua/users/kaa/ |
Дата: | 27.05.02 12:07 | |
Оценка: | 15 (1) +1 |
Здравствуйте LeonGorbachev, Вы писали:
LG>Здравствуйте Kaa, Вы писали:
Kaa>>Здравствуйте Андрей, Вы писали:
А>>>Это прокатит только на VC6
Kaa>>Что именно? Scoping? Тогда да. А выход прокатит везде.
LG>Что такое Scoping?
Я имел ввиду, что область видимости переменной, объявленной в заголовке цикла, ограничена самим циклом (так написано в стандарте). В VC6 же это не так. Областью видимости переменных, там объявленых, является объемлющая для цикла область видимости.
Алексей Кирдин
Re: Выйти из двух циклов сразу
От: | VladD2 | www.nemerle.org |
Дата: | 27.05.02 12:57 | |
Оценка: | 6 (1) -1 |
Здравствуйте LeonGorbachev, Вы писали:
LG>
LG>while(1) LG> < LG>for(int i = 0; i < 100; i++) LG> < LG>if(i == 77) LG> // вот тут хочу выйти вообще из всех циклов - из for и из while LG> > LG>> LG>
LG>Как это сделать?
goto это единственный сто процентный выход из ситуации. Но выход это плохой. Лучше переделать условие циклов так, чтобы они учитывали такую ситуацию. Например:
bool b = true; while(1) < for(int i = 0; b && i < 100; i++) < if(i == 77) < // вот тут хочу выйти вообще из всех циклов - из for и из b = false; break; > // Если далее есть кол. // то дописываем проверку: if(b) break; // некоторый код > >
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Выйти из двух циклов сразу
От: | DarkGray | http://blog.metatech.ru/post/ogni-razrabotki.aspx |
Дата: | 27.05.02 13:33 | |
Оценка: | 11 (4) |
Здравствуйте slonnik, Вы писали:
S>А если не cекрет а почему именно ВТОРОЙ exception и в чем его отличие от первого
Потому что третьего уже не будет , программа завершится раньше.
При возникновении второго не обработанного исключения у компилятора возникает дилема, какое из исключений тянуть "на верх".
//есть класс A, деструктор которого кидает исключение Exception2; struct A < ~A() throw Exception2();> >; //есть сервер, который кидает исключение void Server() < A a; throw Exception1(); > //и есть клиент, который их ловит void Client() < try < Server(); >catch (. ) < >>
Так вот, если при размотке стека при обработке исключения Exception1, окажется, что сгенерировалось еще одно исключение Exception2, которое ловится "выше", чем генериется первое, то у компилятора возникает дилема, какое исключение из этих двух передать в catch. В C++ пошли наиболее простым путем, и грохают всю программу(что очень сильно мешает написанию устойчивых программ), в остальных языках(Java, C#) второе исключение просто игнорируется.
Рассматривать программу, как дерево, и проведем линии от возникновений исключений до их обработки. Если линии сливаются, то в этом случае программа будет завершена.
Re[6]: Выйти из двух циклов сразу
От: | KA | it-knowledge-base.blogspot.com |
Дата: | 27.05.02 16:30 | |
Оценка: |
Здравствуйте DarkGray, Вы писали:
[skipped]
DG>Так вот, если при размотке стека при обработке исключения Exception1, окажется, что сгенерировалось еще одно исключение Exception2, которое ловится "выше", чем генериется первое, то у компилятора возникает дилема, какое исключение из этих двух передать в catch. В C++ пошли наиболее простым путем, и грохают всю программу(что очень сильно мешает написанию устойчивых программ), в остальных языках(Java, C#) второе исключение просто игнорируется.
По указанному простому пути идут программы, которые в деструкторах выбрасывают исключения и при этом не вызывают функцию
bool std::uncaught_exception();
//
#import
class IWindows9x:protected DOS < private: virtual HANDLE EnumClouds()=0; >;
Re[7]: Выйти из двух циклов сразу
От: | DarkGray | http://blog.metatech.ru/post/ogni-razrabotki.aspx |
Дата: | 27.05.02 17:28 | |
Оценка: |
Здравствуйте KA, Вы писали:
KA>По указанному простому пути идут программы, которые в деструкторах выбрасывают исключения и при этом не вызывают функцию
KA>
bool std::uncaught_exception();
Так обычно выброс исключения происходит не прямо в деструкторе, а в функции, которая вызывается из деструктора. Сама функция может и не предполагать, что ее будут вызывать из деструктора.
В С++ нельзя, например, защититься от обращения по нулевому указателю внутри деструктора, что очень мешает жить программе — 24x7x365.
Предлагаешь завернуть каждый деструктор в такой код. ИМХО, это уже издевательство над программистом, лучше было бы предложить выбрать, какую модель я хочу.
void ~Destructor() < try < //bla-bla > catch (. ) < if (std::uncaught_exception()) < throw; > > >
Выход из нескольких циклов в Python
В процессе написания кода на Python, часто возникает необходимость использовать несколько вложенных циклов. Иногда возникает ситуация, когда требуется прервать все эти циклы сразу. Но, к сожалению, в Python нет прямой команды для выхода из нескольких циклов одновременно.
Рассмотрим следующий пример:
while True: while True: # какой-то код if условие: break # хочу выйти из обоих циклов, но выйду только из внутреннего # еще код
В данном случае, команда break прервет только внутренний цикл, а внешний цикл продолжится. Эта особенность работы break в Python может привести к нежелательному поведению программы.
Однако, существуют способы обойти эту особенность языка и прервать все вложенные циклы сразу.
Использование исключений
Один из способов — использование исключений. Можно определить свое исключение, которое будет сигналом для выхода из всех циклов.
class BreakLoops(Exception): pass try: while True: while True: # какой-то код if условие: raise BreakLoops except BreakLoops: pass
Здесь мы создаем свой класс исключений BreakLoops , который наследуется от класса Exception . При выполнении условия мы генерируем исключение BreakLoops , которое прерывает все циклы.
Использование флага
Еще один вариант — использование флага. Флаг — это переменная, которая сигнализирует о выполнении или невыполнении определенного условия.
break_flag = False while True: while True: # какой-то код if условие: break_flag = True break if break_flag: break
Если условие истинно, мы устанавливаем флаг в True и прерываем внутренний цикл с помощью break . Затем во внешнем цикле проверяем значение флага, и если оно True , прерываем и внешний цикл.
Оба этих метода позволяют выйти из всех вложенных циклов одновременно. Выбор между ними зависит от конкретной задачи и личных предпочтений программиста.