É possível usar a breakfunção para sair de vários forloops aninhados ?
Se sim, como você faria isso? Você também pode controlar quantos ciclos as breaksaídas?
É possível usar a breakfunção para sair de vários forloops aninhados ?
Se sim, como você faria isso? Você também pode controlar quantos ciclos as breaksaídas?
Respostas:
AFAIK, C ++ não suporta loops de nomeação, como Java e outras linguagens. Você pode usar um goto ou criar um valor de sinalizador usado. No final de cada loop, verifique o valor do sinalizador. Se estiver definido como true, você poderá interromper essa iteração.
gotose essa for a melhor opção.
goto: programadores ruins e programadores pragmáticos. Os primeiros são auto-explicativos. O último, no qual você se encaixaria se optar por usá-los bem, usa o chamado conceito de "mal" quando é o menor dos (dois) males. Leia isso para entender melhor alguns conceitos de C ++ que você pode precisar usar de tempos em tempos (macros, goto's, pré-processador, matrizes): parashift.com/c++-faq-lite/big-picture.html#faq-6.15
gotoraramente é a melhor opção. Por que não colocar os loops em sua própria função ( inlinese você está preocupado com a velocidade) e returncom isso?
Não, não estrague tudo com um break. Esta é a última fortaleza restante para o uso de goto.
Apenas para adicionar uma resposta explícita usando lambdas:
for (int i = 0; i < n1; ++i) {
[&] {
for (int j = 0; j < n2; ++j) {
for (int k = 0; k < n3; ++k) {
return; // yay we're breaking out of 2 loops here
}
}
}();
}
Claro que esse padrão tem certas limitações e, obviamente, apenas C ++ 11, mas acho que é bastante útil.
Outra abordagem para interromper um loop aninhado é fatorar os dois loops em uma função separada e a returnpartir dessa função quando você deseja sair.
Obviamente, isso traz outro argumento sobre se você deve explicitamente alguma vez returnde uma função em outro lugar que não seja o final.
continue_processing) que controlavam a execução de blocos de código mais abaixo na função.
break sairá apenas do loop mais interno que o contém.
Você pode usar o goto para interromper qualquer número de loops.
É claro que o goto é frequentemente considerado nocivo .
é apropriado usar a função de interrupção [...]?
Usar break e goto pode dificultar o raciocínio sobre a correção de um programa. Veja aqui uma discussão sobre isso: Dijkstra não era louco .
breakou return.
breake returntenha a vantagem de gotonão precisar procurar um rótulo para descobrir para onde ele vai. Sim, por baixo eles são algum tipo goto, mas muito restrito. Eles são muito mais fáceis de decifrar pelo cérebro de correspondência de padrões de um programador do que pelo irrestrito goto. Então IMO são preferíveis.
goto.
Embora essa resposta já tenha sido apresentada, acho que uma boa abordagem é fazer o seguinte:
for(unsigned int z = 0; z < z_max; z++)
{
bool gotoMainLoop = false;
for(unsigned int y = 0; y < y_max && !gotoMainLoop; y++)
{
for(unsigned int x = 0; x < x_max && !gotoMainLoop; x++)
{
//do your stuff
if(condition)
gotoMainLoop = true;
}
}
}
gotoMainLoopé verificado a cada ciclo #
gototorna o núcleo mais legível e com melhor desempenho.
Que tal agora?
for(unsigned int i=0; i < 50; i++)
{
for(unsigned int j=0; j < 50; j++)
{
for(unsigned int k=0; k < 50; k++)
{
//Some statement
if (condition)
{
j=50;
k=50;
}
}
}
}
Um exemplo de código usando gotoe um rótulo para interromper um loop aninhado:
for (;;)
for (;;)
goto theEnd;
theEnd:
Uma boa maneira de interromper vários loops aninhados é refatorar seu código em uma função:
void foo()
{
for(unsigned int i=0; i < 50; i++)
{
for(unsigned int j=0; j < 50; j++)
{
for(unsigned int k=0; k < 50; k++)
{
// If condition is true
return;
}
}
}
}
Goto pode ser muito útil para quebrar loops aninhados
for (i = 0; i < 1000; i++) {
for (j = 0; j < 1000; j++) {
for (k = 0; k < 1000; k++) {
for (l = 0; l < 1000; l++){
....
if (condition)
goto break_me_here;
....
}
}
}
}
break_me_here:
// Statements to be executed after code breaks at if condition
Eu acho que a gotoé válido nesta circunstância:
Para simular um break/ continue, você deseja:
for ( ; ; ) {
for ( ; ; ) {
/*Code here*/
if (condition) {
goto theEnd;
}
}
}
theEnd:
for ( ; ; ) {
for ( ; ; ) {
/*Code here*/
if (condition) {
i++;
goto multiCont;
}
}
multiCont:
}
i. Por isso, i++antes do goto
Outras linguagens como o PHP aceitam um parâmetro para break (isto é, break 2;) para especificar a quantidade de níveis de loop aninhados dos quais você deseja interromper, o C ++, no entanto, não. Você precisará resolver isso usando um booleano que você definiu como false antes do loop, definido como true no loop, se você deseja interromper, além de uma quebra condicional após o loop aninhado, verificando se o booleano foi definido como true e quebre se sim.
Eu sei que este é um post antigo. Mas eu sugeriria uma resposta um pouco lógica e mais simples.
for(unsigned int i=0; i < 50; i++)
{
for(unsigned int j=0; j < conditionj; j++)
{
for(unsigned int k=0; k< conditionk ; k++)
{
// If condition is true
j= conditionj;
break;
}
}
}
j = conditionjnão funcionará se você tiver um predicado complexo em vez de j < conditionj.
Quebre qualquer número de loops por apenas uma boolvariável, veja abaixo:
bool check = true;
for (unsigned int i = 0; i < 50; i++)
{
for (unsigned int j = 0; j < 50; j++)
{
for (unsigned int k = 0; k < 50; k++)
{
//Some statement
if (condition)
{
check = false;
break;
}
}
if (!check)
{
break;
}
}
if (!check)
{
break;
}
}
Neste código, break;todos os loops.
Não tenho certeza se vale a pena, mas você pode emular os loops nomeados do Java com algumas macros simples:
#define LOOP_NAME(name) \
if ([[maybe_unused]] constexpr bool _namedloop_InvalidBreakOrContinue = false) \
{ \
[[maybe_unused]] CAT(_namedloop_break_,name): break; \
[[maybe_unused]] CAT(_namedloop_continue_,name): continue; \
} \
else
#define BREAK(name) goto CAT(_namedloop_break_,name)
#define CONTINUE(name) goto CAT(_namedloop_continue_,name)
#define CAT(x,y) CAT_(x,y)
#define CAT_(x,y) x##y
Exemplo de uso:
#include <iostream>
int main()
{
// Prints:
// 0 0
// 0 1
// 0 2
// 1 0
// 1 1
for (int i = 0; i < 3; i++) LOOP_NAME(foo)
{
for (int j = 0; j < 3; j++)
{
std::cout << i << ' ' << j << '\n';
if (i == 1 && j == 1)
BREAK(foo);
}
}
}
Outro exemplo:
#include <iostream>
int main()
{
// Prints:
// 0
// 1
// 0
// 1
// 0
// 1
int count = 3;
do LOOP_NAME(foo)
{
for (int j = 0; j < 3; j++)
{
std::cout << ' ' << j << '\n';
if (j == 1)
CONTINUE(foo);
}
}
while(count-- > 1);
}
Você pode usar try ... catch.
try {
for(int i=0; i<10; ++i) {
for(int j=0; j<10; ++j) {
if(i*j == 42)
throw 0; // this is something like "break 2"
}
}
}
catch(int e) {} // just do nothing
// just continue with other code
Se você precisar interromper vários loops de uma só vez, geralmente é uma exceção.
Quebrar um loop for é um pouco estranho para mim, uma vez que a semântica de um loop for indica que ele executará um número especificado de vezes. No entanto, não é ruim em todos os casos; se você estiver procurando por algo em uma coleção e quiser quebrar depois de encontrá-lo, é útil. A quebra de loops aninhados, no entanto, não é possível em C ++; está em outros idiomas através do uso de uma quebra rotulada. Você pode usar um rótulo e ir embora, mas isso pode causar azia à noite ..? Parece ser a melhor opção.