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

时间:2017-02-06 22:42:28

标签: c++ switch-statement

我遇到了类似这样的代码:

  switch(i) {
    case 2: {
      std::cout << "2";
      break;
    case 3:
      std::cout << "3";
      break;
    }
    case 4: {
      std::cout << "4";
      break;
    }    
  }

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

2 个答案:

答案 0 :(得分:9)

您可以(但不应该)滥用案例标签switch远比这更糟糕 - 而且远比Duff's Device差。 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;
}

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

基本上,case标签(和default)必须在switch的范围内,并且与最内层的switch相关联。它们几乎没有其他限制。您必须小心不要跳过变量初始化等(这就是jkswitch()之外定义的原因。但除此之外,它们只是标签,当“适当”时控制将流向它们。

答案 1 :(得分:6)

C / C ++中的

switch语句是一个美化的goto语句(具有一些优化优势)。

因此,您可以使用case标签与goto标签一样多。特别是,只要您没有绕过任何变量初始化,就允许在块内跳转。