是否可以使用break函数退出几个嵌套的for循环?

如果是,你会怎么做呢?你还能控制刹车出多少圈吗?


当前回答

我不确定这样做是否值得,但你可以用一些简单的宏来模拟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);
}

其他回答

我知道这是老帖子了。但我想提出一个更合理、更简单的答案。

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

break语句终止它出现的最近的封闭do、for、switch或while语句的执行。控制权转移到终止语句后面的语句。

从msdn。

我的建议是使用一个检查变量来打破一个期望的循环。结果代码可能不那么令人愉快。 您可以使用预处理器,以便在引擎盖下进行所需的破坏。这种方法可以隐藏丑陋的代码和额外的复杂性。 例如,我创建了自定义中断机制,如下所示:

想要的代码:

for (int i = 0; i < 100; i++) {
    for (int j = 0; j < 100; j++) {
        for (int k = 0; k < 100; k++) {
            //do something
            if (desiredCondition) {
                breakToLevel = 0;
            }
            if (breakToLevel < 3) {
                break;
            }
        }
        if (breakToLevel < 2) {
            break;
        }
    }
    if (breakToLevel < 1) {
        break;
    }
}

宏定义:

#define BREAK_TO(L) breakToLevel = (L); 
#define CHECK_BREAK(L) if (breakToLevel < (L)) break; 

和结果:

for (int i = 0; i < 100; i++) {
    for (int j = 0; j < 100; j++) {
        for (int k = 0; k < 100; k++) {
            //do something
            if (desiredCondition) {
                BREAK_TO(0)
            }
            CHECK_BREAK(3)
        }
        CHECK_BREAK(2)
    }
    CHECK_BREAK(1)
}
 bool found = false;
    
    for(int i=0; i < m; ++i){
        for(int j=0; j < n; ++j)
            if(grid[i][j] == '*'){
                q.push(make_pair(i,j));
                found = true;
                break;
            }
        if(found)
            break;
    }

Breaking out of a for-loop is a little strange to me, since the semantics of a for-loop typically indicate that it will execute a specified number of times. However, it's not bad in all cases; if you're searching for something in a collection and want to break after you find it, it's useful. Breaking out of nested loops, however, isn't possible in C++; it is in other languages through the use of a labeled break. You can use a label and a goto, but that might give you heartburn at night..? Seems like the best option though.