您的位置:首页 > 编程语言 > C语言/C++

switch内部的变量定义

2017-01-16 18:09 190 查看
转自 http://blog.csdn.net/u012372584/article/details/38903005
————————————————————————

C++primer:

对于switch结构,只能在它的最后一个case标号或default标号后面定义变量:

case true:

// error:declaration precedes a case label, skipped by case false.

string file_name=get_file_name();

break;

case fal
4000
se:

//…

制定这个规则是为了避免出现代码跳过变量的定义和初始化的情况。回顾变量的作用域,变量从它的定义点开始有效,直到它所在块结束为止。现在考虑如果在两个case标号之间定义变量会出现什么情况。该变量会在块结束之前一直存在。对于定义该变量的标号后面的其他case标号,它们所关联的代码都可以使用这个变量。如果switch从那些后续case标号开始执行,那么这个变量可能还未定义就要使用了。这种情况下,如果需要为某个特殊的case定义变量,则可以引入块语句,在该块语句中定义变量,从而保证这个变量在使用前被定义和初始化。

case true:

{

//ok:declaration statement within a statement block

string file_name=get_file_name();

//…

}

break;

case false:

//…

——————————————————————————————–

上面明确了在switch语句内定义一个变量的时候有三种情况:

(1)可在default中定义;

(1)可在最后一个case中定义;

(3)在某个特殊的case中定义变量,但必须引入块语句。

上面规则出现的原因:

在C++中,switch-case中的case实质上只是一个标签(label),case中的代码并没有构成一个局部作用域,虽然它的缩进好像是一个作用域。即,所有在case里面定义的变量作用域都是switch{…},所以在后面其他case中依然可以访问到这个变量。

举个例子:

[cpp] view plain copy print?



switch (a)
{
case 1:
int m = 1;//(1)编译出错
break;
case 2:
{
int n = 3;//(2)编译通过,引入块语句
}
break;
case 3:
int c =3;//(3)编译通过,最后一个case
cout<<”ss”<<endl;//输出ss
break;
}</span>


switch (a)
{
case 1:
int m = 1;//(1)编译出错
break;
case 2:
{
int n = 3;//(2)编译通过,引入块语句
}
break;
case 3:
int c =3;//(3)编译通过,最后一个case
cout<<"ss"<<endl;//输出ss
break;
}</span>


分析:

C++规定:如果一个程序的执行路径从代码中的点A(某个局部变量x还未定义)跳到代码中另一点B(该局部变量x已定义,并且定义的时候有初始化),那么编译器会报错。这样的跳跃可以是由于执行goto语句或是switch-case语句造成的。

上面的程序如果从switch直接跳到case2,就发生了与C++规定不相符的情况。在switch时m还没有定义,但是到达case2后m已经定义,并且被初始化,这样m被直接跳过,编译就会出错。

但是如果把: int m = 1; 改成: int m; 编译就不会出错。原因是跳过声明时不报错,可能会有警告,只有跳过有初始化的声明时才会报错。

如果真的需要在中间某个case里定义变量,则简单的解决办法是引入块语句,在该块语句中定义变量。

之所以在最后一个case和default中可以定义变量,是因为在这里面定义的变量是不可能被其他case引用的,因为其作用域不可能向上扩展。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息