我可以使用break退出多个嵌套的“for”吗?循环?
是否可以使用 break
函数退出多个嵌套的 for
循环?
如果是这样,你会怎样做呢?您还可以控制 break
退出多少个循环吗?
Is it possible to use the break
function to exit several nested for
loops?
If so, how would you go about doing this? Can you also control how many loops the break
exits?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(20)
不,不要用
break
破坏它。这是使用goto
的最后一个据点。No, don't spoil it with a
break
. This is the last remaining stronghold for the use ofgoto
.AFAIK,C++ 不支持命名循环,就像 Java 和其他语言一样。您可以使用 goto,或创建您使用的标志值。在每个循环结束时检查标志值。如果它设置为 true,那么您可以跳出该迭代。
AFAIK, C++ doesn't support naming loops, like Java and other languages do. You can use a goto, or create a flag value that you use. At the end of each loop check the flag value. If it is set to true, then you can break out of that iteration.
只是使用 lambda 添加一个明确的答案:
当然,这种模式有一定的限制,显然仅限 C++11,但我认为它非常有用。
Just to add an explicit answer using lambdas:
Of course this pattern has a certain limitations and obviously C++11 only but I think it's quite useful.
打破嵌套循环的另一种方法是将两个循环分解为一个单独的函数,并在您想要退出时从该函数
返回
。当然,这会带来另一个论点,即是否应该从函数末尾以外的任何地方显式返回。
Another approach to breaking out of a nested loop is to factor out both loops into a separate function, and
return
from that function when you want to exit.Of course, this brings up the other argument of whether you should ever explicitly
return
from a function anywhere other than at the end.break 将仅退出包含它的最内层循环。
您可以使用goto来打破任意数量的循环。
当然,goto 通常被认为是有害的 。
使用break和goto会使推断程序的正确性变得更加困难。请参阅此处有关此问题的讨论:Dijkstra 并不疯狂。
break will exit only the innermost loop containing it.
You can use goto to break out of any number of loops.
Of course goto is often Considered Harmful.
Using break and goto can make it more difficult to reason about the correctness of a program. See here for a discussion on this: Dijkstra was not insane.
这个怎么样?
How about this?
使用
goto
和标签来跳出嵌套循环的代码示例:A code example using
goto
and a label to break out of a nested loop:尽管这个答案已经提出,但我认为一个好的方法是执行以下操作:
Although this answear was already presented, i think a good approach is to do the following:
我知道这是一个老话题,但我觉得这确实需要说,而且没有其他地方可以说。对于这里的每个人,请使用goto。我刚刚使用过它。
与几乎所有事物一样,goto 并不是 100% 要么/异或“坏”或“好”。我想说的是,至少有两种用途,如果您对它们使用 goto - 并且不将其用于其他任何用途 - 您不仅应该 100% 没问题,而且您的程序将比没有它更具可读性,因为它使您的意图更加清晰(有很多方法可以避免它,但我发现它们都更加笨拙):
不要教条地接受诸如“马马虎虎”之类的规则,而要理解为什么要表达这种观点,并遵循“为什么”,而不是情绪。不知道这一点也给我带来了很多麻烦,以至于我想说,教条地称事物为“邪恶”可能比事物本身更有害。最坏的情况是,你只是得到了糟糕的代码——然后只要你听说要小心谨慎,你就知道你没有正确使用它,但如果你为了满足教条主义而折磨自己,我会说那更糟糕。
为什么“goto”被称为“邪恶”是因为你永远不应该用它来代替普通的 if、fors 和 while。为什么呢?尝试一下,尝试一直使用“goto”代替普通的控制逻辑语句,然后尝试用控制逻辑再次编写相同的代码,并告诉我哪一个看起来更好、更容易理解,哪一个看起来更混乱。就这样吧。 (奖励:现在尝试向仅限 goto 的代码添加一个新功能。)这就是为什么它是“邪恶”的,并且围绕“邪恶”有适当的范围限定。用它来弥补 C 的“
break
”命令的缺点不是一个有问题的用法,只要你从代码中明确你的 goto 应该做什么完成(例如使用“nestedBreak”之类的标签)。打破嵌套循环是非常自然的。(或者更简单地说:使用 goto 来跳出循环。我想说这更好。不要使用 goto 创建循环。< em>那是“邪恶”。)
你怎么知道你是否教条主义?如果遵循“xyz 是邪恶的”规则导致您的代码不太易于理解,因为您扭曲自己试图绕过它(例如在每个循环上添加额外的条件或一些标志变量,或类似的其他技巧),那么你很可能是教条主义的。
学习良好的思维习惯比良好的编码习惯更重要,这是无可替代的。前者先于后者,而一旦前者被采用,后者往往也会随之而来。然而,问题是,我经常发现后者解释得不够。太多人只是简单地说“这很糟糕”和“这需要更多思考”,而没有说思考什么、关于思考什么以及为什么 。这是一个很大的耻辱。
(FWIW,在 C++ 中,仍然存在打破嵌套循环的需要,但不再需要错误代码:在这种情况下,始终使用异常来处理错误代码,永远不要返回它们,除非它会如此频繁地导致异常抛出和捕获将导致性能问题,例如在高要求服务器代码的紧密循环中,也许[有些人可能会说“异常”应该“很少使用”,但这是考虑不周的教条主义的另一部分:不,至少根据我在打破这一教条后的经验,我发现它们使事情变得更加清晰 - 只是不要滥用它们来做除错误处理之外的事情,例如将它们用作有效的控制流;与“goto”一样。如果您全部使用它们并且仅用于错误处理,那就是它们的用途。]。)
I know this is an old thread but I feel this really needs saying and don't have anywhere else to say it. For everybody here, use goto. I just used it.
Like almost everything, goto is not 100% either/xor "bad" or "good". There are at least two uses where I'd say that if you use a goto for them - and don't use it for anything else - you should not only be 100% okay, but your program will be even more readable than without it, as it makes your intention that much clearer (there are ways to avoid it, but I've found all of them to be much clunkier):
Instead of just dogmatically accepting rules like "so-so is 'evil'", understand why that sentiment is claimed, and follow the "why", not the letter of the sentiment. Not knowing this got me in a lot of trouble, too, to the point I'd say calling things dogmatically "evil" can be more harmful than the thing itself. At worst, you just get bad code - and then you know you weren't using it right so long as you heard to be wary, but if you are wracking yourself trying to satisfy the dogmatism, I'd say that's worse.
Why "goto" is called "evil" is because you should never use it to replace ordinary ifs, fors, and whiles. And why that? Try it, try using "goto" instead of ordinary control logic statements, all the time, then try writing the same code again with the control logic, and tell me which one looks nicer and more understandable, and which one looks more like a mess. There you go. (Bonus: try and add a new feature now to the goto-only code.) That's why it's "evil", with suitable scope qualification around the "evil". Using it to short-circuit the shortcomings of C's "
break
" command is not a problematic usage, so long as you make it clear from the code what your goto is supposed to accomplish (e.g. using a label like "nestedBreak" or something). Breaking out of a nested loop is very natural.(Or to put it more simply: Use goto to break out of the loop. I'd say that's even preferable. Don't use goto to create the loop. That's "evil".)
And how do you know if you're being dogmatic? If following an "xyz is evil" rule leads your code to be less understandable because you're contorting yourself trying to get around it (such as by adding extra conditionals on each loop, or some flag variable, or some other trick like that), then you're quite likely being dogmatic.
There's no substitute for learning good thinking habits, moreso than good coding habits. The former are prior to the latter and the latter will often follow once the former are adopted. The problem is, however, that far too often I find, the latter are not explicated enough. Too many simply say "this is bad" and "this needs more thought" without saying what to think, what to think about, and why. And that's a big shame.
(FWIW, in C++, the need to break out of nested loops still exists, but the need for error codes does not: in that case, always use exceptions to handle error codes, never return them unless it's going to be so frequent that the exception throw and catch will be causing a performance problem, e.g. in a tight loop in a high demand server code, perhaps [some may say that 'exceptions' should be 'used rarely' but that's another part of ill-thought-out dogmatism: no, at least in my experience after bucking that dogma I find they make things much clearer - just don't abuse them to do something other than error handling, like using them as control flow; effectively the same as with "goto". If you use them all and only for error handling, that's what they're there for.].)
打破多个嵌套循环的一种好方法是将代码重构为函数:
One nice way to break out of several nested loops is to refactor your code into a function:
我不确定这是否值得,但是您可以使用一些简单的宏来模拟 Java 的命名循环:
示例用法:
另一个示例:
I'm not sure if it's worth it, but you can emulate Java's named loops with a few simple macros:
Example usage:
Another example:
goto 对于打破嵌套循环非常有帮助
goto can be very helpful for breaking nested loops
我确实认为
goto
在这种情况下是有效的:要模拟
break
/continue
,您需要:Break
Continue
I do think a
goto
is valid in this circumstance:To simulate a
break
/continue
, you'd want:Break
Continue
来自 msdn。
from msdn.
我的建议是使用检查变量来打破所需的循环。结果代码可能不太令人愉快。
您可以使用预处理器来进行所需的底层破坏。这种方法可以隐藏丑陋的代码和额外的复杂性。
例如,我创建了自定义中断机制,如下所示:
想要的代码:
定义的宏:
和结果:
My suggestion is use a check variable to break a desired loop. The result code may not be so pleasant.
You can use preprocessors in order to make desired breaking under the hood. This approach can hides ugly codes and extra complexity.
For example, I created my custom break mechanism as follow:
Wanted code:
Defined macros:
and result:
您必须使用在循环之前设置为 false 的布尔值来解决此问题,如果要中断,则在循环中设置为 true,再加上嵌套循环之后的条件中断,检查布尔值是否设置为 true如果是的话就打破。
You will have to work it out by using a boolean that you set to false prior to the loop, set to true in the loop if you want to break, plus a conditional break after the nested loop, checking if the boolean was set to true and break if yes.
我知道这是旧帖子。但我会建议一个更合乎逻辑且更简单的答案。
I know this is old post . But I would suggest a bit logical and simpler answer.
只需一个
bool
变量即可中断任意数量的循环,如下所示:在此代码中,我们
break;
所有循环。Break any number of loops by just one
bool
variable see below :In this code we
break;
all the loops.最优雅的方式是使用异常。
异常是指遇到不正常的情况,这种情况不仅可以是太糟糕的情况,也可以是太好的情况。
例如,您正在寻找具有 3 个嵌套 for 循环的 3d 数组中的元素。 正常情况是“当前不是我正在寻找的”。 异常情况是“当前就是这样”。
请记住错误和异常之间的区别。异常不一定是错误,它可能是一个好消息。
The most graceful way is to use exception.
Exception means encountering an abnormal situation, which can not only be a too bad situation but also be a too good situation.
For example you are looking for an element in a 3d array with 3 nested for-loops. The normal situation is "The current is NOT the one I'm looking for". The abnormal situation is "The current IS the one".
Remember the difference between error and exception. An exception doesn't have to be an error, it can be a good news.
您可以使用 try...catch。
如果您必须同时跳出多个循环,那么无论如何它通常都是一个例外。
You can use try...catch.
If you have to break out of several loops at once, it is often an exception anyways.