对于switch的break语句,是否有更好的编程语言?

语法太多,语法相同:

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语句都是必需的,因为当缺少break语句时, switch将继续下一个case 。 我们有一个OPTION_LIKE_ONEOPTION_ONE_SIMILAROPTION_TWO_WITH_PRE_ACTION 。 问题是我们很少需要这个“跳到下一个案例”。 我们经常在case结束时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中有这样的历史意义? 可能会继续使用下一个案例的次数远远超过我们现在使用的情况吗?

在本文中,我可以枚举一些不需要类似break语句的语言:

  1. 阿达(没有通过)
  2. 埃菲尔(没有穿透)
  3. 帕斯卡(没有通过)
  4. Go – fallthrough
  5. Perl – continue
  6. Ruby(没有穿透)
  7. VB,VBA,VBS,VB.NET(没有通过)
  8. 待别人继续……

你的第二个问题非常有趣。 假设只有C, 我相信这个决定能保持语言的凝聚力。 由于break是一个跳转 ,因此必须明确写入。

我认为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的样本

而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,根本没有掉头

答案如下: http : //en.wikipedia.org/wiki/Switch_statement

它被称为fall-through语句(在示例中continue ),它以下列语言存在:
Go,Perl,C#

在C#中,如果没有breakgoto case语句,它将无法编译(除非没有预先操作)。

PASCAL没有堕落

我认为你的问题的答案是以这种方式为中心的两个行为,都与C源生成的汇编代码有关。

第一个是在汇编中,执行当前指令,除非有跳转或其他流控制指令,否则将执行下一个地址的指令。 执行switch语句到程序集的简单编译将生成只会开始执行第一条指令的代码,这将是查看是否存在匹配条件…

第二个相关原因是分支表或跳转列表的概念。 基本上,编译器可以获取它对您的值的了解,并为同一事物创建一些非常高效的机器代码。 以像atoi这样的简单函数为例,它转换数字的字符串表示并以整数forms返回。 简化事情以支持一个数字,您可以编写一些类似于此的代码:

 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

嘿,别忘了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. 

Ada没有漏洞,并且要求显式处理所有值,或者添加“others”子句来处理其余值。

SQL CASE语句也没有落实。 XSLT没有落空。

它似乎是C和派生语言的突破。 这是非常阴险的,我见过的唯一真正用途是实现duff的设备 。

http://www.adaic.org/whyada/intro4.html

Python根本就没有。

采取了一些习惯,但我有一些可怕的记忆,通过我的C#天回击大量的switch块。 没有它,我会更开心。

虽然不完全是你要求的,但Groovy有一个非常强大的switch语句

OP谈到“堕落”,但我很少有人对此表示赞同。

很多次,但是我的设计是不可扩展的。 也就是说,“切换(kbHit)”语句,其中有几百个键,这是一个维护噩梦,以及“神方法”的常用位置,以及大堆的意大利面条代码。

使用开关通常是面向对象编程不良的标志。 正如另一个人回答的那样,“在48个源文件中使用Switch”,在他的一个应用程序中,显示了一个程序员,他并没有严重依赖这个结构。 根据他的指标,我猜测他可能至少是一个优秀的结构化程序员,并且可能也理解OOP / OOD。

OOP(不一定只是C ++)程序员,甚至是没有强制使用对象描述技术的纯C用户,可以实现“控制反转”容器,该容器发布“密钥被击中”并允许订阅者插入他们的“键盘代码x”的处理程序。 这可以使您更轻松地阅读代码。

纯粹的猜测,但是:

我偶尔写C或Java,其中我说的是:

 switch (tranCode) { case 'A': case 'D': case 'R': processCredit(); break; case 'B': case 'G': processDebit(); break; default: processSpecial(); } 

也就是说,我故意使用fall-thru让几个值触发相同的操作。

我想知道这是C的发明者在创建SWITCH语句时想到的,这是正常的用法。

Tcl不会自动失效。

在面向对象语言中,您使用“ 责任链”模式。 如何实施可能会有所不同。 您在示例中描述的是通过滥用switch语句将状态机与行为混合在一起。 对于您的特定示例,一个责任链模式,其中链条评估的参数是一个状态模式,随着链条向下变化,将是适当的实现。

语言太多了,我无法回答肯定没有这样的语言,只要它是语法中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. 

更多没有语言的语言:

XSLT JSTL Algol PL / 1

利马这样做:

 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[]