switch case 语句内部变量定义
来源:互联网 发布:吉他谱曲软件 编辑:程序博客网 时间:2024/05/19 02:26
switch case语句是非常常用的语句,入门的码农也知道是做什么的。
但关于switch case内定义变量的问题,网上的很多博文都有谬误,在这里我写一下对这个语句的了解。
一
先看合法的定义方式:
int main(int argc, const char * argv[]) { int idx = 2; switch (idx) { int k; case 1: int j; break; case 2: k = 1; j = 2; std::cout<<"K:"<<k<<std::endl; std::cout<<"J:"<<j<<std::endl; break; default: break; } return 0;}
在C++11 std Dialect下 打印出的结果是:
K:1J:2
二
然后看看不合法的写法:
int main(int argc, const char * argv[]) { int idx = 2; switch (idx) { int k = 1; case 1: int j = 1; break; case 2: k = 1; j = 2; std::cout<<"K:"<<k<<std::endl; std::cout<<"J:"<<j<<std::endl; break; default: break; } return 0;}
编译无法通过。
三
解释下原因:
一为什么合法?
首先一个变量有没有被定义是在编译时就检查过的,因此这里可以编译通过。
其次在处理switch case语句中,C++11标准的编译器都会在执行case跳转前为变量分配空间,因此执行也没有问题。
(当然我并不建议在case语句外定义变量,因为何时为变量分配空间是编译器特性,而非语言特性,虽然这个问题中遵守C++11标准的编译器没有问题)
二为什么不合法?
C++11标准禁止这种写法。在编译时,编译器就会报错。C++11禁止这种写法的原因来自于C++的一个规定:
It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps from a point where a local variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has POD type (3.9) and is declared without an initializer. (The transfer from the condition of a switch statement to a case label is considered a jump in this respect.)
众所周知,C++不允许使用未初始化的变量,而初始化操作和定义变量对于编译器来说是两码事,初始化操作是一个确确实实的在运行时才会被调用的语句,是可以被case跳转屏蔽掉的语句,而定义则是在编译器就完成检查的。
如果二的写法合法的话,那么会发生这样的问题:
编译时定义变量被执行,初始化和赋值语句也用各自的方式编译完成,并且在运行时,程序也的确为此变量分配了空间。但是在运行时,初始化语句却在某些情况下被跳转掉了。
虽然对于int等类型的变量,赋值和初始化在我们看来都是"=",但编译后的二进制是完全不同的,编译器会在编译时把"int j = 1;"编译成初始化,而把"j = 1;"编译成赋值。因此在整个运行过程中,如果初始化语句被case跳转掉了,我们在其他case语句中的"="不可能对此变量进行初始化。
这时,如果在整个switch(){}的定义域中,有对此变量的调用,那就是『试图在初始化一个变量前使用它』,因此C++11禁止了这种写法。
四
额外谈一些:
如果不在case中加上{},整个switch(){}都是使用同一个作用域,这一点通过上文符合语法例子中对J、K的定义和使用就能看出来。最好的方法就是在编码时,将整个switch语句用到的变量在switch外声明,并且针对某个case需要单独使用变量的情况,用{}明确此case语句的作用域
case的实现与goto非常相似,case的本质是一种标签,在switch case语句中变量的定义问题可以推广到goto语句中。
下面的代码也是不合法的,因为string是一个类,类有自己的隐式初始化方法,实际上这依然是个可能被跳转掉的初始化语句。
case 1: std::string tempStr; break;
- switch case 语句内部变量定义
- switch 语句内部变量的定义问题
- C语言switch case语句中定义变量问题
- switch case中变量定义
- switch内部的变量定义
- switch内部的变量定义
- switch内部的变量定义
- switch case关于定义变量的规定
- 易错点:C++ switch case中定义变量
- C++中switch case 中定义变量
- case语句中的变量定义
- switch内部的变量定义(转)
- 请教switch内部的变量定义问题?
- c++ switch内部的变量定义
- switch语句中case语句中变量初始化问题!
- switch case语句里面不能定义对象 错误信息:Cannot jump from switch statement to this case..
- switch-case 中的分支中变量定义 编译不通过问题
- 在switch-case中定义变量时当心被“穿越”
- 基于B/S模式分布式图书管理系统研究
- Android开发总结笔记 Spannable(文本样式[上]) 1-1-6-2
- Sql数据库学习
- 20个快乐的习惯
- 软件测试基础知识
- switch case 语句内部变量定义
- 各种数据库连接方式
- 根据客户区大小反推窗口大小
- CentOS源码安装gftp缺失stropts.h
- Ubuntu中文路径改英文路径
- javascript基础资料
- [优化篇]Ubuntu使用corosync+pacemaker+drbd实现MySQL的HA(1)
- java学习_反射
- 泛型委托