在JavaScript中,以下语句有效。
switch(true) {
case a > b:
max = a;
break;
case a < b:
max = b;
break;
default:
max = a;
}
但是在C / C ++编程语言中,当我编写这个语句时,编译器给出了一个错误,表明 case语句必须由常量值组成。有时在特殊情况下编写这样的switch-case语句会非常有用,但C / C ++不允许我这样做。
现在我很想知道不允许在 case语句中使用变量值的原因是什么?
答案 0 :(得分:32)
C ++已经从C演变而来,其中switch语句被设想为Jump Table (Branch Table)。要实现跳转表,切换条件应该是常量,以便可以很容易地转换为标签。
虽然标准从不规定如何实现switch语句,但最重要的是,case标签应该能够在编译期间进行评估。在C和C ++中,switch语句计算表达式并将控制转移到许多case语句值中的一个,这些值的计算结果为条件表达式的值。
6.4.2 switch语句[stmt.switch]
switch语句使控制权转移到多个语句之一,具体取决于条件的值。
此行为使其与支持case语句中的条件的其他语言不同。
对于实例,Javascript将switch ... case
语句描述为
switch语句计算表达式,将表达式的值与case子句匹配,并执行与该case相关的语句。
因此,您实际上是在尝试比较两种不同的构造,并期望行为是相同的。
至于回答the point behind this to not allowing variable values to be used in case statements?
,这会使switch .. case
效率降低,对于每个迭代/实例,应重新评估案例标签以确定它是否与条件表达式匹配。
答案 1 :(得分:15)
C(而不是C ++)标准说:
每个
case
标签的表达式应为整数常量表达式,并且同一case
语句中的switch
个常量表达式中没有两个在转换后具有相同的值。[...]
如果在case
中允许表达式,那么两个表达式可能具有相同的值。
C ++(而不是C)标准说的相同:
[...]在转换为提升类型的开关条件后,同一开关中的两个外壳常量应具有相同的值。
答案 2 :(得分:10)
switch
/ case
存在的原因(请记住if
/ else
存在于其他所有内容)是为较低级别的“跳转”提供模拟“语法,以便您可以为您的代码创建快速,静态的”jump tables“。如果允许运行时表达式,那么这个原因就会消失。
询问为什么 switch
这件事情类似于问为什么if
做了另一件事,因此是空的。
答案 3 :(得分:9)
仅仅因为你可以做某事并不意味着有意义。特别是,switch
不等同于if/else
阶梯。
if/else
比switch
更通用,它旨在根据切换表达式&#34;选择要做的事情。
练习 - 以下代码会做什么?
var a = 5;
var b = 0;
switch(a)
{
case 5: b = 1; break;
case 5: b = 2; break;
case 1: b = 3; break;
}
现在b
是否等于2
或1
?如果它同时执行两个分支,则它不会选择一个要做的事情,如果它做了一个而不是另一个,那么它就是任意的决定。
将case值限制为常量表达式允许编译器对此代码发出错误。如果值可能因运行时的值而不同,则由于暂停问题,编译器无法验证两个案例是否具有相同的值。