int i;
i = 2;
switch(i)
{
case 1:
int k;
break;
case 2:
k = 1;
cout << k << endl;
break;
}
我不知道为什么上面的代码有效。
在这里,我们永远无法进入情况 1,但为什么我们可以在情况 2 中使用
k
?
实际上有2个问题:
1。为什么我可以在
case
标签之后声明变量?
这是因为在C++中标签必须采用形式:
N3337 6.1/1
标签声明:
...
- 属性说明符-seqopt
case
:constant-expression
statement
...
并且在
C++
中,声明语句也被视为语句(与C
相对):
N3337 6/1:
声明:
...
- 声明声明
...
2。为什么我可以跳过变量声明然后使用它?
因为: N3337 6.7/3
可以转移到一个块中,但不能以绕过初始化声明的方式。 A 跳跃的程序 (在这方面,从switch 语句的条件到 case 标签的转移被视为跳转。)
从具有自动存储持续时间的变量不在范围内的点到其在范围内的点都是格式错误的除非变量具有标量类型,具有简单默认值的类类型 构造函数和一个简单的析构函数,这些类型之一的 cv 限定版本,或者其中之一的数组 前面的类型,并且在没有初始化器的情况下声明 (8.5)。
由于
k
是标量类型,并且在声明点没有初始化,因此可以跳过它的声明。这在语义上是等价的:
goto label;
int x;
label:
cout << x << endl;
但是,如果
x
在声明时初始化,这将不起作用:
goto label;
int x = 58; //error, jumping over declaration with initialization
label:
cout << x << endl;