switch分支作用域问题
我们做条件选择时,经常会用到switch语句,相信大家对于它的使用也都是得心应手。前几天有人问我switch分支中为什么使用临时变量会报错,借此就写了个简单的Demo演示了一把,有疑问的小伙伴可以参照Demo亲自测试一下,实践才是检验真理的唯一标准。以下是错误程序,小伙伴们不妨瞜一眼先,看自己平时是不是也是这样编写的,而只是碰巧平时没有在case分支中使用临时变量罢了。
#if 1
#include <iostream>
enum PROTOCOL_TYPE
{
TCP = 0x00,
UDP = 0x01,
ARP = 0x10,
HTTP = 0x11,
FTP = 0x100,
SSH = 0x101
};
void protocolExchange(PROTOCOL_TYPE cType)
{
switch (cType)
{
case TCP:
std::cout << "TCP协议" << std::endl;
break;
case UDP:
int cType = '1';
std::cout << "UDP协议" << cType << std::endl;
break;
case ARP:
std::cout << "ARP协议" << std::endl;
break;
case HTTP:
std::cout << "HTTP协议" << std::endl;
break;
case FTP:
std::cout << "FTP协议" << std::endl;
break;
case SSH:
std::cout << "SSH协议" << std::endl;
break;
default:
std::cout << "未知协议" << std::endl;
break;
}
}
int main(int argc, char **argv)
{
protocolExchange(TCP);
protocolExchange(UDP);
return 0;
}
#endif
win 10系统,Visual Studio 2013编辑器,编译报错如下
1>------ 已启动生成: 项目: MainTest, 配置: Debug Win32 ------
1> main.cpp
1>d:\project\c++\maintest\maintest\main.cpp(25): error C2360: “cType”的初始化操作由“case”标签跳过
1> d:\project\c++\maintest\maintest\main.cpp(22) : 参见“cType”的声明
1>d:\project\c++\maintest\maintest\main.cpp(28): error C2360: “cType”的初始化操作由“case”标签跳过
1> d:\project\c++\maintest\maintest\main.cpp(22) : 参见“cType”的声明
1>d:\project\c++\maintest\maintest\main.cpp(31): error C2360: “cType”的初始化操作由“case”标签跳过
1> d:\project\c++\maintest\maintest\main.cpp(22) : 参见“cType”的声明
1>d:\project\c++\maintest\maintest\main.cpp(34): error C2360: “cType”的初始化操作由“case”标签跳过
1> d:\project\c++\maintest\maintest\main.cpp(22) : 参见“cType”的声明
1>d:\project\c++\maintest\maintest\main.cpp(37): error C2361: “default”标签跳过“cType”的初始化操作
1> d:\project\c++\maintest\maintest\main.cpp(22) : 参见“cType”的声明
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
Red Hat Enterprise Linux Server release 6.4 (Santiago),gcc 版本 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC),编译报错如下
$ g++ test.cpp
test.cpp: In function ‘void protocolExchange(PROTOCOL_TYPE)’:
test.cpp:25: 错误:跳转至 case 标号
test.cpp:22: 错误: 跳过‘int cType’的初始化
test.cpp:28: 错误:跳转至 case 标号
test.cpp:22: 错误: 跳过‘int cType’的初始化
test.cpp:31: 错误:跳转至 case 标号
test.cpp:22: 错误: 跳过‘int cType’的初始化
test.cpp:34: 错误:跳转至 case 标号
test.cpp:22: 错误: 跳过‘int cType’的初始化
test.cpp:37: 错误:跳转至 case 标号
test.cpp:22: 错误: 跳过‘int cType’的初始化
错误原因为switch分支作用域问题。系统不允许我们在case中定义一个变量,原因是我们在一个case中定义的变量,假如在另一个case中被使用就会出现错误,因为一般来说switch语句中的case只能被执行一个,当然你也可以多个case合并(这个不是本篇博文重点,就不在此处赘述了)。如果想在case分支中使用临时变量,需要显示说明一下临时变量的作用域,在用到临时变量的case分支加上块作用域即可,也就是用“{}”括起来。建议我们在写case语句时给每一个case都加上“{}”,养成一个良好的编码习惯。
此处作为演示,仅给“UDP”分支添加块作用域,保证编译正确。
#if 1
#include <iostream>
enum PROTOCOL_TYPE
{
TCP = 0x00,
UDP = 0x01,
ARP = 0x10,
HTTP = 0x11,
FTP = 0x100,
SSH = 0x101
};
void protocolExchange(PROTOCOL_TYPE cType)
{
switch (cType)
{
case TCP:
std::cout << "TCP协议" << std::endl;
break;
case UDP:
{
int cType = '1';
std::cout << "UDP协议" << cType << std::endl;
}
break;
case ARP:
std::cout << "ARP协议" << std::endl;
break;
case HTTP:
std::cout << "HTTP协议" << std::endl;
break;
case FTP:
std::cout << "FTP协议" << std::endl;
break;
case SSH:
std::cout << "SSH协议" << std::endl;
break;
default:
std::cout << "未知协议" << std::endl;
break;
}
}
int main(int argc, char **argv)
{
protocolExchange(TCP);
protocolExchange(UDP);
return 0;
}
#endif
编译通过,运行结果如下
【visual studio 2013】
TCP协议
UDP协议49
请按任意键继续. . .
【gcc 4.4.7】
$ g++ test.cpp
$ ./a.out
TCP协议
UDP协议49
好了,Demo演示到此结束,相信你对switch以及块作用域又有了新的认知。更多内容请关注博主分享的其他博文,相信你会有更多新的认知。好好学习,天天向上!