我们应该在switch语句中打破默认情况吗?

57

假设这个例子的代码(原代码):

#include <stdio.h>

void playgame()
{
    printf( "Play game called" );
}
void loadgame()
{
    printf( "Load game called" );
}
void playmultiplayer()
{
    printf( "Play multiplayer game called" );
}

int main()
{
    int input;

    printf( "1. Play game\n" );
    printf( "2. Load game\n" );
    printf( "3. Play multiplayer\n" );
    printf( "4. Exit\n" );
    printf( "Selection: " );
    scanf( "%d", &input );
    switch ( input ) {
        case 1:            /* Note the colon, not a semicolon */
            playgame();
            break;
        case 2:
            loadgame();
            break;
        case 3:
            playmultiplayer();
            break;
        case 4:
            printf( "Thanks for playing!\n" );
            break;
        default:
            printf( "Bad input, quitting!\n" );
            break;
    }
    getchar();

    return 0;
}

我们在最后一个 default 中使用 break; 吗?如果我移除它,程序的行为似乎没有变化。但是,我发现其他示例中也在 default 中使用了 break;

为什么呢?有什么理由吗?


14
如果最后一个case标签是最后一个,那么在它之后不需要添加break。无论是default还是其他标签都和此无关。 - WhozCraig
使用选项-pedantic,最近版本的gcc会在最后一个case后缺少break时发出警告。 - alk
@alk,没有这个标志,Eclipse警告了我。这是编译命令:gcc -std=c99 -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.c"。也许-Wall就足够了。 - gsamaras
1
也许-Wall就足够了。更好! :-) - alk
7个回答

111
我们应该在最后一个默认情况下使用break;吗?
来自《C语言程序设计 - 第二版》(K&R 2):
第3.4章 开关
出于良好的形式,即使逻辑上不必要,在最后一个case(这里是默认情况)后放置一个break。某一天当在末尾添加另一个case时,这种防御性编程将会拯救你。

14

首先,你应该思考为什么我们在switch语句中要使用break。看一下这个没有使用break的switch语句。


switch ( input ) {
    case 1:            /* Note the colon, not a semicolon */
        playgame();
    case 2:
        loadgame();
    case 3:
        playmultiplayer();
    case 4:
        printf( "Thanks for playing!\n" );
    default:
        printf( "Bad input, quitting!\n" );
}
假设 input == 1。程序当然会调用 playgame(),但由于没有 break,程序不会完成 switch 而是顺序调用 loadgame()playmultiplayer()、两个 printf
为避免这种情况,我们使用 break
case 1:
    playgame();
    break; /* here */
case 2:
    ...

由于break语句,程序在执行case 2代码之前就结束了switch语句。这是我们期望的结果,不是吗?

你的switch语句如下:

switch ( input ) {
    case 1:            /* Note the colon, not a semicolon */
        playgame();
        break;
    case 2:
        loadgame();
        break;
    case 3:
        playmultiplayer();
        break;
    case 4:
        printf( "Thanks for playing!\n" );
        break;
    default:
        printf( "Bad input, quitting!\n" );
        break;
}

由于default后面没有case,所以无论您是否在default上写break都没有影响。 但是,您可以轻松地假设编写一个新的case

    default:
        printf( "Thanks for playing!\n" );
        /* what happens if there's no `break`...? */
    case 5:
        the_new_feature();
        break;
}

在C/C++中,这是常见错误。如果您在5年后添加新功能并完全忘记它,则它将成为一个非常有缺陷的错误。一些现代语言(例如C#,...)甚至禁止使用没有breakreturn的switch-case。

结论:这在语法上没有问题,但这是非常糟糕的实践,强烈建议使用break


在default之后放一个case是被允许的吗? - Rodrigo
3
是的,@Rodrigo。 - JakeD

9

这要取决于默认情况的书写方式

在下面的情况中,必须使用break

switch ( input ) {
    default:
        printf( "Bad input, quitting!\n" );
        break;
    case 1:            /* Note the colon, not a semicolon */
        playgame();
        break;
    case 2:
        loadgame();
        break;
}

正确,但问题的意思是默认情况是最后一个。我会进行编辑,抱歉。 - gsamaras

2

如果您省略或保留break语句,实际上并没有什么区别,这只是个人口味而已。

然而,有不同的原因建议写break语句,这是一个良好的编程习惯。

请参考程序员交流论坛了解更多相关信息。


2
如果default语句是在最后一个位置,那么break语句就没有用了。如果它在其他case之前,则需要break语句。由于通常我们将default放在最后,因此可以省略它。

这里不仅适用于default情况,而且所有情况都适用。 - Spikatrix
@Cool Guy 是的.. 但他在询问默认情况。 - Rustam

1

Break似乎是可选的

break在这种情况下似乎是可选的,您的代码几乎可以正常工作。

然而

在许多情况下添加break可以改善您的代码,并保护代码免受错误或异常的影响。

它增加了可读性、一致性和更少的错误。

一些语言如C#,在最后一个选择项之后技术上需要使用break(或其他退出该分支的控制流语句)。 dan04

因此,为了更好的编程实践,我建议应该使用它。

请参阅此优秀的文章以获取更多详细信息。


0

实际上,在默认情况下,您不需要break。并且在您的检查中,如果在默认情况下没有break,则相同。

但是,在我看来,您应该在默认情况下使用break,因为:

  1. 它使您的代码在每种情况下都有一个形式。
  2. 它对当前编译器很好,但可能与特定的其他编译器不兼容。因此,您应该使其良好以防止未来出现问题。

这里的行为对于所有编译器来说都是一样的。 - arye

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接