8.11 — Break 和 continue

Break

尽管你已经在 switch 语句的上下文中看到过 break 语句(8.5 -- Switch 语句基础),但它值得更全面的介绍,因为它也可以用于其他类型的控制流语句。break 语句会导致 while 循环、do-while 循环、for 循环或 switch 语句结束,执行将继续进行到循环或 switch 语句后的下一条语句。

中断 switch

switch 语句的上下文中,break 通常用于每个 case 的末尾,以表示 case 已完成(这可以防止执行落入后续 case)

#include <iostream>

void printMath(int x, int y, char ch)
{
    switch (ch)
    {
    case '+':
        std::cout << x << " + " << y << " = " << x + y << '\n';
        break; // don't fall-through to next case
    case '-':
        std::cout << x << " - " << y << " = " << x - y << '\n';
        break; // don't fall-through to next case
    case '*':
        std::cout << x << " * " << y << " = " << x * y << '\n';
        break; // don't fall-through to next case
    case '/':
        std::cout << x << " / " << y << " = " << x / y << '\n';
        break;
    }
}

int main()
{
    printMath(2, 3, '+');

    return 0;
}

有关执行落入以及其他示例的更多信息,请参阅课程 8.6 -- Switch 执行落入和作用域

中断循环

在循环的上下文中,break 语句可以用于提前结束循环。执行将继续进行到循环结束后的下一条语句。

例如

#include <iostream>

int main()
{
    int sum{ 0 };

    // Allow the user to enter up to 10 numbers
    for (int count{ 0 }; count < 10; ++count)
    {
        std::cout << "Enter a number to add, or 0 to exit: ";
        int num{};
        std::cin >> num;

        // exit loop if user enters 0
        if (num == 0)
            break; // exit the loop now

        // otherwise add number to our sum
        sum += num;
    }

    // execution will continue here after the break
    std::cout << "The sum of all the numbers you entered is: " << sum << '\n';

    return 0;
}

此程序允许用户输入最多 10 个数字,并在最后显示所有输入数字的总和。如果用户输入 0,则 break 会导致循环提前终止(在输入 10 个数字之前)。

以下是上述程序的示例执行

Enter a number to add, or 0 to exit: 5
Enter a number to add, or 0 to exit: 2
Enter a number to add, or 0 to exit: 1
Enter a number to add, or 0 to exit: 0
The sum of all the numbers you entered is: 8

break 也是退出有意无限循环的常见方式

#include <iostream>

int main()
{
    while (true) // infinite loop
    {
        std::cout << "Enter 0 to exit or any other integer to continue: ";
        int num{};
        std::cin >> num;

        // exit loop if user enters 0
        if (num == 0)
            break;
    }

    std::cout << "We're out!\n";

    return 0;
}

上述程序的示例运行

Enter 0 to exit or any other integer to continue: 5
Enter 0 to exit or any other integer to continue: 3
Enter 0 to exit or any other integer to continue: 0
We're out!

Break 与 return

新程序员有时难以理解 breakreturn 之间的区别。break 语句终止 switch 或循环,执行在 switch 或循环之外的第一条语句处继续。return 语句终止循环所在的整个函数,执行在函数被调用的点处继续。

#include <iostream>

int breakOrReturn()
{
    while (true) // infinite loop
    {
        std::cout << "Enter 'b' to break or 'r' to return: ";
        char ch{};
        std::cin >> ch;

        if (ch == 'b')
            break; // execution will continue at the first statement beyond the loop

        if (ch == 'r')
            return 1; // return will cause the function to immediately return to the caller (in this case, main())
    }

    // breaking the loop causes execution to resume here

    std::cout << "We broke out of the loop\n";

    return 0;
}

int main()
{
    int returnValue{ breakOrReturn() };
    std::cout << "Function breakOrReturn returned " << returnValue << '\n';

    return 0;
}

以下是此程序的两次运行

Enter 'b' to break or 'r' to return: r
Function breakOrReturn returned 1
Enter 'b' to break or 'r' to return: b
We broke out of the loop
Function breakOrReturn returned 0

Continue

continue 语句提供了一种方便的方式来结束循环的当前迭代,而无需终止整个循环。

以下是使用 continue 的示例

#include <iostream>

int main()
{
    for (int count{ 0 }; count < 10; ++count)
    {
        // if the number is divisible by 4, skip this iteration
        if ((count % 4) == 0)
            continue; // go to next iteration

        // If the number is not divisible by 4, keep going
        std::cout << count << '\n';

        // The continue statement jumps to here
    }

    return 0;
}

此程序打印 0 到 9 之间所有不能被 4 整除的数字

1
2
3
5
6
7
9

continue 语句通过使当前执行点跳转到当前循环的底部来工作。

对于 for 循环,for 循环的结束语句(在上面的示例中为 ++count)在 continue 之后仍然会执行(因为它发生在循环体结束之后)。

在使用 continue 语句与 while 或 do-while 循环时要小心。这些循环通常在循环体内部更改条件中使用的变量的值。如果使用 continue 语句导致这些行被跳过,则循环可能会变成无限循环!

考虑以下程序

#include <iostream>

int main()
{
    int count{ 0 };
    while (count < 10)
    {
        if (count == 5)
            continue; // jump to end of loop body

        std::cout << count << '\n';

        ++count; // this statement is never executed after count reaches 5

        // The continue statement jumps to here
    }

    return 0;
}

此程序旨在打印 0 到 9 之间的所有数字,除了 5。但它实际上打印

0
1
2
3
4

然后进入无限循环。当 count5 时,if 语句评估为 truecontinue 导致执行跳转到循环底部。count 变量从不递增。因此,在下一次传递中,count 仍然是 5if 语句仍然是 true,程序继续永远循环。

当然,你已经知道,如果你有一个明显的计数器变量,你应该使用 for 循环,而不是 whiledo while 循环。

关于 break 和 continue 使用的争论

许多教科书告诫读者不要在循环中使用 breakcontinue,既因为它会导致执行流跳转,也因为它会使逻辑流更难跟踪。例如,复杂逻辑中间的 break 可能会被遗漏,或者在什么条件下应该触发它可能不明显。

然而, judiciously 使用 breakcontinue 可以通过减少嵌套块的数量和减少复杂循环逻辑的需要来帮助使循环更具可读性。

例如,考虑以下程序

#include <iostream>

int main()
{
    int count{ 0 }; // count how many times the loop iterates
    bool keepLooping { true }; // controls whether the loop ends or not
    while (keepLooping)
    {
        std::cout << "Enter 'e' to exit this loop or any other character to continue: ";
        char ch{};
        std::cin >> ch;

        if (ch == 'e')
            keepLooping = false;
        else
        {
            ++count;
            std::cout << "We've iterated " << count << " times\n";
        }
    }

    return 0;
}

此程序使用布尔变量控制循环是否继续,以及仅在用户不退出时运行的嵌套块。

以下是更易于理解的版本,使用 break 语句

#include <iostream>

int main()
{
    int count{ 0 }; // count how many times the loop iterates
    while (true) // loop until user terminates
    {
        std::cout << "Enter 'e' to exit this loop or any other character to continue: ";
        char ch{};
        std::cin >> ch;

        if (ch == 'e')
            break;

        ++count;
        std::cout << "We've iterated " << count << " times\n";
    }

    return 0;
}

在此版本中,通过使用单个 break 语句,我们避免了使用布尔变量(以及不得不理解其预期用途以及其值在哪里更改)、else 语句和嵌套块。

continue 语句最有效地用于 for 循环的顶部,以便在满足某些条件时跳过循环迭代。这可以让我们避免嵌套块。

例如,而不是这样:

#include <iostream>

int main()
{
    for (int count{ 0 }; count < 10; ++count)
    {
        // if the number is not divisible by 4...
        if ((count % 4) != 0) // nested block
        {
                // Print the number
                std::cout << count << '\n';
        }
    }

    return 0;
}

我们可以这样写

#include <iostream>

int main()
{
    for (int count{ 0 }; count < 10; ++count)
    {
        // if the number is divisible by 4, skip this iteration
        if ((count % 4) == 0)
            continue;

        // no nested block needed

        std::cout << count << '\n';
    }

    return 0;
}

最小化使用的变量数量并减少嵌套块的数量都比 breakcontinue 损害代码可理解性更有益。因此,我们认为 judiciously 使用 breakcontinue 是可以接受的。

最佳实践

breakcontinue 简化你的循环逻辑时使用它们。

关于提前返回的争论

对于 return 语句也有类似的论点。不是函数中最后一条语句的 return 语句称为提前返回。许多程序员认为应该避免提前返回。只在函数底部有一个 return 语句的函数具有简单性——你可以假设函数将接收其参数,执行其已实现的任何逻辑,并返回结果而不会出现偏差。拥有额外的返回会使逻辑复杂化。

反驳的论点是,使用提前返回允许你的函数在完成后立即退出,这减少了阅读不必要的逻辑的需要,并最大限度地减少了条件嵌套块的需要,这使得你的代码更具可读性。

一些开发人员采取中间立场,只在函数顶部使用提前返回来执行参数验证(捕获传入的错误参数),然后只有一个 return。

我们的立场是,提前返回利大于弊,但我们认识到这种做法有点艺术性。

最佳实践

当它们简化你的函数逻辑时使用提前返回。

guest
您的电子邮箱地址将不会被显示
发现错误?请在上方留言!
与勘误相关的评论在处理后将被删除,以帮助减少混乱。感谢您帮助使网站对每个人都更好!
来自 https://gravatar.com/ 的头像与您提供的电子邮箱地址相关联。
有回复时通知我:  
157 评论
最新
最早 最多投票
内联反馈
查看所有评论