C++ c++;:为什么我们可以在开关的情况下声明一个变量 inti; i=2; 开关(一) { 案例1: int k; 打破 案例2: k=1; cout

C++ c++;:为什么我们可以在开关的情况下声明一个变量 inti; i=2; 开关(一) { 案例1: int k; 打破 案例2: k=1; cout,c++,variables,initialization,switch-statement,C++,Variables,Initialization,Switch Statement,实际上有两个问题: 1.为什么我可以在caselabel之后声明变量? 这是因为C++标签必须是形式: N3337 6.1/1 标记语句: 属性说明符seqopt大小写常量表达式:语句 在C++中,声明语句也被视为语句(与C相反): N3337 6/1: 声明: 声明 2.为什么我可以跳过变量声明,然后使用它? 因为: N3337 6.7/3 可以传输到块中,但不能以通过初始化绕过声明的方式传输 跳转程序 (在这方面,将开关语句的条件转移到案例标签被视为跳转。) 从具有自动存储持

实际上有两个问题:

1.为什么我可以在
case
label之后声明变量?

这是因为C++标签必须是形式:

N3337 6.1/1

标记语句:

  • 属性说明符seqopt
    大小写
    常量表达式
    语句

C++
中,声明语句也被视为语句(与
C
相反):

N3337 6/1:

声明:

  • 声明

2.为什么我可以跳过变量声明,然后使用它?

因为: N3337 6.7/3

可以传输到块中,但不能以通过初始化绕过声明的方式传输 跳转程序 (在这方面,开关语句的条件转移到案例标签被视为跳转。)

从具有自动存储持续时间的变量不在作用域内的点到它在作用域内的点是格式错误的,除非该变量具有标量类型,类类型具有一个微不足道的默认值 构造函数和普通析构函数、这些类型之一的cv限定版本或其中一个类型的数组 前面的类型和声明没有初始值设定项(8.5)

由于
k
是标量类型,并且在声明点未初始化,因此可以跳过其声明。这在语义上是等价的:

int i;
i = 2;
switch(i)
{
    case 1: 
        int k;
        break;
    case 2:
        k = 1;
        cout<<k<<endl;
        break;
}

你认为这很糟糕吗?看看开关很奇怪;如果你在寻找作用域,{}你是你的朋友。@TemplateRex这个问题是关于你为什么不能。这个问题是关于你为什么可以。@Barry,尽管如此,上面的答案确实很好地解释了这个问题。@Barry potato,po tah to,链接问答的第一个答案深入探讨了切换范围
goto label;

int x;

label:
cout << x << endl;
 goto label;

    int x = 58; //error, jumping over declaration with initialization

    label:
    cout << x << endl;