为什么案件陈述允许在另一个案件的内部?

Den*_*kiy 9 c++ switch-statement

我遇到过这样的代码:

  switch(i) {
    case 2: {
      std::cout << "2";
      break;
    case 3:
      std::cout << "3";
      break;
    }
    case 4: {
      std::cout << "4";
      break;
    }    
  }
Run Code Online (Sandbox Code Playgroud)

请注意,case 2打开一个带花括号的块,只有在后才会关闭case 3.起初,这似乎是一个错字导致编译器错误,或者更糟糕的是,忽略case 3.但它在c ++中运行得很好,如果我是3则输出3.我来自java背景,所以我对c ++中逻辑块的理解可能缺乏.所以我的问题是:这是故意的行为吗?

Jon*_*ler 9

你可以,但不应该,滥用案例标签switch远比这更糟糕 - 甚至比Duff的设备更糟糕.Duff的设备具有几乎可能有用的可疑特权,但可以被视为滥用switch.

并非所有滥用switch权利都可以说是合理有用的.例如,即使设置了严格的警告,这也会编译成C或C++:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(int argc, char **argv)
{
    unsigned seed;
    if (argc == 2)
        seed = atoi(argv[1]);
    else
        seed = time(0);
    printf("seed: %u\n", seed);
    srand(seed);

    int i = rand() % 10;
    int j = 21;
    int k = 37;
    printf("i: %d\n", i);
    switch (i)
    {
    case 1:
        for (j = 10; j > i; j--)
        {
        case 2:
            printf("case 2:\n");
            for (k = j - 1; k > 0; k--)
            {
            case 6:
                printf("case 6:\n");
            default:
                printf("%d-%d-%d\n", i, j, k);
            }
        case 5:
            printf("case 5:\n");
            printf("%d-%d\n", i, j);
            break;
        }
        break;
    case 3:
        printf("case 3:\n");
        break;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

参数处理允许您设置种子,因此您可以根据需要重现结果.我没有声称它有用; 实际上,它没用.请注意,break循环内部会打破循环,而不是循环switch.

基本上,case标签(和default)必须在a的范围内switch,并与最里面的封闭相关联switch.它们几乎没有其他限制.你必须小心不要跳过变量初始化等(这就是为什么jk在外面定义switch()).但除此之外,它们只是标签,当"适当"时,控制权将流向它们.


Ser*_*eyA 6

switchC/C++中的goto语句是一个美化的声明(具有一些优化的好处).

因此,您可以使用case标签执行与goto标签相同的操作.特别是,只要您没有绕过任何变量初始化,就允许在块内跳转.