【问题标题】:c++: why can we declare a variable in case of switchc ++:为什么我们可以在switch的情况下声明一个变量
【发布时间】:2016-09-18 23:38:27
【问题描述】:
int i;
i = 2;
switch(i)
{
    case 1: 
        int k;
        break;
    case 2:
        k = 1;
        cout<<k<<endl;
        break;
}

我不知道为什么上面的代码有效。

在这里,我们永远无法进入案例 1,但为什么我们可以在案例 2 中使用k

【问题讨论】:

  • 你认为这很糟糕?看Duff's Device
  • 开关比较奇怪;如果您正在寻找范围,{} 是您的朋友。
  • @TemplateRex 这个问题是关于为什么你不能。这个问题是关于为什么你可以。
  • @Barry,不过,最佳答案确实很好地解释了这一点。
  • @Barry potato, po-tah-to,链接问答的第一个答案深入探讨了切换范围

标签: c++ variables initialization switch-statement


【解决方案1】:

其实有2个问题:

1.为什么case标签后面可以声明变量?

这是因为在 C++ 中标签必须是格式:

N3337 6.1/1

标签声明:

...

  • attribute-specifier-seqopt case constant-expression : statement

...

并且在C++声明语句也被认为是语句(相对于C):

N3337 6/1:

声明

...

  • 声明声明

...

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

因为: N3337 6.7/3

可以转移到一个块中,但不能以绕过初始化声明的方式。一种 跳跃的程序 (在这方面,从 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;

【讨论】:

    猜你喜欢
    • 2014-06-20
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 2016-02-29
    • 2010-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多