语法太多,语法相同:
switch (someValue) {
case OPTION_ONE:
case OPTION_LIKE_ONE:
case OPTION_ONE_SIMILAR:
doSomeStuff1();
break; // EXIT the switch
case OPTION_TWO_WITH_PRE_ACTION:
doPreActionStuff2();
// the default is to CONTINUE to next case
case OPTION_TWO:
doSomeStuff2();
break; // EXIT the switch
case OPTION_THREE:
doSomeStuff3();
break; // EXIT the switch
}
现在所有人都知道break
语句是必需的,因为当switch
语句丢失时,case
会继续到下一个break
。我们有OPTION_LIKE_ONE
,OPTION_ONE_SIMILAR
和OPTION_TWO_WITH_PRE_ACTION
的示例。问题是我们只需要非常非常非常需要“跳到下一个案例”。我们经常在case
结束时放假。
初学者很容易忘记它。我的一位C老师甚至向我们解释过,好像这是C语言的一个错误(不想谈论它)。
我想问一下我是否还有其他语言(或忘了)处理这样的开关/案例:
switch (someValue) {
case OPTION_ONE: continue; // CONTINUE to next case
case OPTION_LIKE_ONE: continue; // CONTINUE to next case
case OPTION_ONE_SIMILAR:
doSomeStuff1();
// the default is to EXIT the switch
case OPTION_TWO_WITH_PRE_ACTION:
doPreActionStuff2();
continue; // CONTINUE to next case
case OPTION_TWO:
doSomeStuff2();
// the default is to EXIT the switch
case OPTION_THREE:
doSomeStuff3();
// the default is to EXIT the switch
}
第二个问题:C中为什么会有这样的历史意义?可能会继续使用下一个案例的次数远远超过我们现在使用的情况吗?
答案 0 :(得分:11)
从this文章中,我可以枚举一些不需要break
类似语句的语言:
fallthrough
continue
你的第二个问题非常有趣。假设只有C,我相信这个决定保持了语言的凝聚力。由于break
是 jump ,因此必须明确写入。
答案 1 :(得分:9)
Scala模式匹配我认为在这些情况下是一个巨大的改进。 :)
object MatchTest2 extends Application {
def matchTest(x: Any): Any = x match {
case 1 => "one"
case "two" => 2
case y: Int => "scala.Int"
}
println(matchTest("two"))
}
来自scala-lang.org的样本
答案 2 :(得分:6)
VB .NET处理它的方式更像你期望它应该如何工作。
Select Case i
Case 1 to 3
DoStuff(i)
Case 4,5,6
DoStuffDifferently(i)
Case Is >= 7
DoStuffDifferentlyRedux(i)
Case Else
DoStuffNegativeNumberOrZero(i)
End Select
根本没有堕落,没有使用Goto
答案 3 :(得分:4)
以下是答案: http://en.wikipedia.org/wiki/Switch_statement
它被称为直通语句(示例中为continue
),它以下列语言存在:
Go,Perl,C#
在C#中,如果没有break
或goto case
语句,则无法编译(除非没有预先行动)。
答案 4 :(得分:3)
PASCAL没有堕落
答案 5 :(得分:3)
我认为你的问题的答案是以这种方式为中心的两个行为,都与C源生成的汇编代码有关。
第一个是在汇编中,执行当前指令,除非有跳转或其他流控制指令,否则将执行下一个地址的指令。执行switch语句到程序集的简单编译会生成只会开始执行第一条指令的代码,这将是查看是否存在匹配条件...
第二个相关原因是branch table or jump list的概念。基本上,编译器可以获取它对您的值的了解,并为同一事物创建一些非常高效的机器代码。例如,像atoi这样的简单函数,它转换数字的字符串表示形式并以整数形式返回。简化事情以支持一个数字,你可以写一些类似的代码:
int atoi(char c) {
switch (c) {
case '0': return 0;
case '1': return 1;
// ....
}
}
天真的编译器可能只是将其转换为一系列if / then块,这意味着对于数字9将采用大量的CPU周期,而0几乎立即返回。使用分支表,编译器可以发出一些[psuedo]程序集,它会立即“跳转”到正确的return子句:
0x1000 # stick value of c in a register
0x1004 # jump to address c + calculated offset
# example '0' would be 0x30, the offset in for this sample
# would always be 0x0FD8... thus 0x30 + 0x0FD8 = 0x1008
0x1008 # return 0
道歉:我的集会和C技能都很生疏。我希望这有助于澄清事情。 0X
答案 6 :(得分:2)
嘿,不要忘记COBOL的评估:
EVALUATE MENU-INPUT
WHEN "0" PERFORM INIT-PROC
WHEN "1" THRU "9" PERFORM PROCESS-PROC
WHEN "R" PERFORM READ-PARMS
WHEN "X" PERFORM CLEANUP-PROC
WHEN OTHER PERFORM ERROR-PROC
END-EVALUATE.
答案 7 :(得分:1)
Ada没有漏洞,并且要求显式处理所有值,或者添加“others”子句以处理其余值。
SQL CASE语句也没有落实。 XSLT并没有落空。
似乎是C语言和派生语言都有这个漏洞。这是非常阴险的,我见过的唯一真正的用途就是实现duff's device。
答案 8 :(得分:1)
纯粹猜测,但是:
我偶尔写C或Java,其中我说的是:
switch (tranCode)
{
case 'A':
case 'D':
case 'R':
processCredit();
break;
case 'B':
case 'G':
processDebit();
break;
default:
processSpecial();
}
也就是说,我故意使用fall-thru让几个值触发相同的操作。
我想知道这是C的发明者在创建SWITCH语句时想到的,这是正常用法。
答案 9 :(得分:1)
很多次,但是我的设计是不可扩展的。也就是说,“切换(kbHit)”语句,其中有几百个键,这是一个维护噩梦,以及“神方法”的常用位置,以及大堆的意大利面条代码。
使用switch通常是面向对象编程不佳的标志。正如另一个人回答的那样,“在48个源文件中使用Switch”,在他的一个应用程序中,显示了一个程序员,他并没有严重依赖这个结构。根据他的指标,我猜测他可能至少是一个优秀的结构化程序员,并且可能也理解OOP / OOD。
OOP(不一定只有C ++)程序员,甚至没有强制使用对象描述技术的纯C用户,可以实现“控制反转”容器,该容器发布“密钥被击中”并允许订阅者插入他们的处理程序“键盘代码x”。这可以使您更轻松地阅读代码。
答案 10 :(得分:1)
虽然不完全符合您的要求,但Groovy有一个very powerful switch statement
答案 11 :(得分:1)
Python根本没有。
我已经习惯了一些人,但是在我的C#时代,我有一些可怕的记忆在追逐大量的switch
块。没有它我会更开心。
答案 12 :(得分:0)
语言太多了我无法回答肯定没有这样的语言,只要它是语法中C的“派生”,因为其他语言使用不同的语法并且案例不会“继续”自然存在,例如Fortran语言。我不知道使用明确的“继续”继续下列情况的语言。
我认为这是历史原因,因为这种情况可以在“低级别”编程。此外,案例的语法方面是标签,而break就像循环一样,所以你可以想象一个像这样的等价物:
if ( case == 1 ) goto lab1;
if ( case == 2 ) goto lab2;
if ( case == 3 ) goto lab3;
//...
default:
// default
goto switch_end;
lab1:
// do things
goto switch_end; // if break is present
lab2:
// do things, and follow to lab3
lab3:
// lab3 stuffs
goto switch_end;
//
...
switch_end: // past all labS.
答案 13 :(得分:0)
在面向对象语言中,您使用Chain of Responsibility模式。如何实施可能会有所不同。您在示例中描述的是通过滥用switch语句将状态机与行为混合在一起。对于您的特定示例,具有链评估为State模式的参数的责任链模式,在其沿着链向下变化时,将是适当的实现。
答案 14 :(得分:0)
Tcl不会自动失效。
答案 15 :(得分:0)
更多没有语言的语言:
XSLT JSTL 大陵 PL / 1
答案 16 :(得分:0)
利马这样做:
if someValue == ?1 ::
OPTION_ONE: fall
OPTION_LIKE_ONE: fall
OPTION_ONE_SIMILAR:
doSomeStuff1[]
;; the default is to EXIT the switch
OPTION_TWO_WITH_PRE_ACTION:
doPreActionStuff2[]
fall ;; fall through to the next case
OPTION_TWO:
doSomeStuff2[]
OPTION_THREE:
doSomeStuff3[]