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

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


当前回答

c++不支持命名循环,就像Java和其他语言一样。您可以使用goto,或创建您使用的标志值。在每个循环结束时检查标志值。如果它被设置为true,那么您可以跳出该迭代。

其他回答

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

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

其他语言如PHP接受break参数(即break 2;)来指定你想要跳出的嵌套循环级别的数量,但c++不接受。你必须使用一个在循环之前设置为false的布尔值,如果你想中断,在循环中设置为true,在嵌套循环之后加上一个条件中断,检查布尔值是否设置为true,如果是则中断。

c++不支持命名循环,就像Java和其他语言一样。您可以使用goto,或创建您使用的标志值。在每个循环结束时检查标志值。如果它被设置为true,那么您可以跳出该迭代。

打破几个嵌套循环的一个好方法是将代码重构为一个函数:

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