Answers:
AFAIK,C ++不像Java和其他语言那样支持命名循环。您可以使用goto或创建使用的标志值。在每个循环结束时,检查标志值。如果将其设置为true,则可以中断该迭代。
goto
如果这是最好的选择,请不要害怕。
goto
:不良程序员和务实的程序员。前者是不言自明的。如果选择使用得当,则会适合后者;当它是(两种)邪恶中的较小者时,则使用所谓的“邪恶”概念。请阅读以下内容,以更好地理解您可能需要不时使用的一些C ++概念(宏,goto,预处理器,数组):parashift.com/c++
goto
很少使用是最好的选择。为什么不将循环放入自己的函数中(inline
如果您担心速度的话),然后return
从中开始呢?
只是使用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
}
}
}();
}
当然,这种模式有一定的局限性,显然只有C ++ 11,但我认为它非常有用。
打破嵌套循环的另一种方法是将两个循环分解为一个单独的函数,并return
在需要退出时从该函数中分解出来。
当然,这提出了另一个论点,即是否应该return
从函数的末尾以外的任何地方显式地进行。
continue_processing
),这些布尔变量控制该函数后面的代码块的执行。
break将仅退出包含它的最里面的循环。
您可以使用goto中断任何数量的循环。
当然goto通常被认为是有害的。
使用break函数是否合适[...]?
使用break和goto会使推理程序的正确性变得更加困难。有关此问题的讨论,请参见此处: Dijkstra并不疯狂。
break
或,这是没有意义的return
。
break
和return
有过的优势goto
,你并不需要寻找一个标签,以便找到他们到何处去。是的,它们下面是某种goto
,但非常受限制。与不受限制的模式相比,它们更容易被程序员的模式匹配大脑所破译goto
。因此,IMO是可取的。
goto
。
尽管已经提出了这个问题,但我认为一种好的方法是执行以下操作:
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
每个周期都会检查一次
goto
会使核心更具可读性和更好的性能。
一个使用goto
和标签打破嵌套循环的代码示例:
for (;;)
for (;;)
goto theEnd;
theEnd:
打破几个嵌套循环的一种好方法是将代码重构为一个函数:
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对于打破嵌套循环可能非常有帮助
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
我确实认为goto
在这种情况下a 是有效的:
要模拟break
/ continue
,您需要:
for ( ; ; ) {
for ( ; ; ) {
/*Code here*/
if (condition) {
goto theEnd;
}
}
}
theEnd:
for ( ; ; ) {
for ( ; ; ) {
/*Code here*/
if (condition) {
i++;
goto multiCont;
}
}
multiCont:
}
i
。因此i++
,在跳转之前
我知道这是旧帖子。但是我建议一个合理且简单的答案。
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 = conditionj
如果您使用而不是复杂的谓词,则该解决方案将不起作用j < conditionj
。
只需一个bool
变量即可中断任意数量的循环,如下所示:
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;
}
}
在这段代码中,我们break;
所有的循环。
我不确定是否值得,但是您可以使用一些简单的宏来模拟Java的命名循环:
#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
用法示例:
#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);
}
}
}
另一个例子:
#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);
}
您可以使用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
如果必须一次跳出几个循环,无论如何通常都是一个例外。