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>
分析:
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引用的,因为其作用域不可能向上扩展。
————————————————————————
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引用的,因为其作用域不可能向上扩展。
相关文章推荐
- PHP8新特性之match表达式
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Ruby教程之注释、变量声明以及数组操作
- 三个有用的 Switch 命令
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例