C语言switch case语句中定义变量问题
2017-08-13 12:20
681 查看
严正声明:
作者:psklf
出处: http://www.cnblogs.com/psklf/p/6702767.html
欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任!
这个问题需要分开讨论,C 语言和 C++ 的标准定义是不同的。
C++
编译报错信息为
也就是说,跳到 case2 的这个地方,忽略了对于 b 这个变量的初始化,这个很直观,就是在这里我找不到 b。
那么如果改成
顺利成功,没有报错,如果 a 为 2,那么输出 b 也是 2,说明逻辑没有问题。那么问题来了,b 在前面声明,为什么后面可以用到呢,因为 switch-case 的逻辑控制就是用 label 来标记跳转的,而不是别的复杂的逻辑控制,所以 b 的作用域是在整个 switch 的花括号内,关于这个问题见知乎讨论请教switch内部的变量定义问题。
C 语言
上面两种写法统统出错,
两种写法都错,报错信息:
意思是说,此处需要一个表达式(expression),而不是一个变量声明初始化。有一个很黑客的做法,如下:
这个很不能理解了,其实也就是说保证 case 后面跟着的确实是 expression 即可。考虑一下 C++ 代码出现的问题:跳过变量的声明?C 语言中同样跳过,但是编译器不认为这个是错误,而且逻辑上面也是没有问题的,在后面的 case 中可以正常给变量赋值,但是如果 case2 中,我不是给 b 赋值,而是直接访问 b,那返回的数值就是一个随机的错误的数据了,我在我的电脑上使用 gcc 编译,若直接读取数据,得到的是 0,当然编译通过,连警告都没有。
当然我认为这样的代码可读性差,比较好的做法可以是将声明变量的事情放在头上做。
但是要留心, switch 和 case 之前那块地方也就只能写写这样的声明,写别的表达式,赋值啊什么的,统统是不会生效的。
作者:psklf
出处: http://www.cnblogs.com/psklf/p/6702767.html
欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任!
这个问题需要分开讨论,C 语言和 C++ 的标准定义是不同的。
C++
int Caset(int a) { switch (a) { case 1: int b = 1; std::cout<<"a==1: "<<b<<std::endl; break; case 2: b = 2; std::cout<<"a==2: "<<b<<std::endl; break; } }
编译报错信息为
simple.cc:35:9: error: cannot jump from switch statement to this case label case 2: ^ simple.cc:32:17: note: jump bypasses variable initialization int b = 1; ^
也就是说,跳到 case2 的这个地方,忽略了对于 b 这个变量的初始化,这个很直观,就是在这里我找不到 b。
那么如果改成
int Caset(int a) { switch (a) { case 1: int b; b = 1; std::cout<<"a==1: "<<b<<std::endl; break; case 2: b = 2; std::cout<<"a==2: "<<b<<std::endl; break; } }
顺利成功,没有报错,如果 a 为 2,那么输出 b 也是 2,说明逻辑没有问题。那么问题来了,b 在前面声明,为什么后面可以用到呢,因为 switch-case 的逻辑控制就是用 label 来标记跳转的,而不是别的复杂的逻辑控制,所以 b 的作用域是在整个 switch 的花括号内,关于这个问题见知乎讨论请教switch内部的变量定义问题。
C 语言
上面两种写法统统出错,
void Caset(int a) { switch (a) { case 1: /* one style */ int b; b = 1; /* another style */ int b = 1; printf("1: %d", b); break; case 2: b = 2; printf("2: %d", b); break; } }
两种写法都错,报错信息:
main.c:12:13: error: expected expression int b; ^ main.c:13:13: error: use of undeclared identifier 'b' b = 1; ^
意思是说,此处需要一个表达式(expression),而不是一个变量声明初始化。有一个很黑客的做法,如下:
void Caset(int a) { switch (a) { case 1: ; int b = 1; // b = 1; printf("1: %d \n", b); break; case 2: b = 2; printf("2: %d \n", b); break; } }
这个很不能理解了,其实也就是说保证 case 后面跟着的确实是 expression 即可。考虑一下 C++ 代码出现的问题:跳过变量的声明?C 语言中同样跳过,但是编译器不认为这个是错误,而且逻辑上面也是没有问题的,在后面的 case 中可以正常给变量赋值,但是如果 case2 中,我不是给 b 赋值,而是直接访问 b,那返回的数值就是一个随机的错误的数据了,我在我的电脑上使用 gcc 编译,若直接读取数据,得到的是 0,当然编译通过,连警告都没有。
当然我认为这样的代码可读性差,比较好的做法可以是将声明变量的事情放在头上做。
void Caset(int a) { switch (a) { int b; case 1: b = 1; // b = 1; printf("1: %d \n", b); break; case 2: b = 2; printf("2: %d \n", b); break; } }
但是要留心, switch 和 case 之前那块地方也就只能写写这样的声明,写别的表达式,赋值啊什么的,统统是不会生效的。
相关文章推荐
- C语言switch case语句中定义变量问题
- C语言switch case语句中定义变量问题
- C语言switch case语句中定义变量问题
- C语言变量声明问题——变量定义一定要放在所有执行语句/语句块的最前面吗?
- switch中case中变量定义的问题
- Switch-case 内定义变量的问题
- C++:在switch的case中定义变量的问题
- 定义一个结构体变量(包括年、月、日),编写程序,要求输入年月日,程序能够计算并输出改日是本年中的第几天。注意闰年问题。(switch语句)
- 关于C语言中switch的case里定义变量解决编译报错
- 在case语句中定义变量的问题
- 在case语句中定义变量的问题
- C语言变量声明问题——变量定义一定要放在所有执行语句/语句块的最前面吗?
- switch语句中case跳过变量初始化的问题
- 在case语句中定义变量的问题
- switch语句中case语句中变量初始化问题!
- switch-case 中的分支中变量定义 编译不通过问题
- 关于C/C++中switch语句case中变量不能初始化赋值的问题
- switch 语句内部变量的定义问题
- C语言中switch case语句可变参实现方法(case 参数 空格...空格 参数 :)
- C语言头文件定义全局变量问题