【问题标题】:In C++, why would they make you put break statements in switch statements? [closed]在 C++ 中,为什么他们会让你将 break 语句放在 switch 语句中? [关闭]
【发布时间】:2010-08-23 01:02:27
【问题描述】:

我知道其中的基本思想是什么,但我在想,并且我意识到,因此一个 switch 语句比一堆 if 语句需要更多的字符。

因为if 语句有 7 个字符(不包括变量名,也不包括它被比较的内容,也不包括代码),而 switch 语句有 9 个字符(同样的东西),因为单词“break ",即使没有它,单词 "case:" 也是 5 个字符,而 if 语句中是 7 个字符,所以它并不比 if 语句好多少!

【问题讨论】:

  • 因为 C++ 不是为了保存字符而编写的。见golfscript.com/golfscript
  • 我不会关闭这个。这是一个合理的问题:在switch 中默认设置失败有什么好处,为什么它们比冗长更重要?
  • 字数是最大的问题?如果您不小心忘记了break,会发生什么?更糟糕的是,当您尝试在一个案例中“失败”时会发生什么,而没有人能弄清楚,添加break 并破坏逻辑?当字符数不相关时,这些不会产生有意义的影响吗?
  • 这确实是一个有效的问题。为什么switch 语句不像循环那样使用continue 语句?在许多情况下,这将是有益的。
  • 主题提出了一个有效的问题,但实际问题过于关注字符数。

标签: c++ switch-statement


【解决方案1】:

这样你就可以做类似的事情

switch (toupper(ch))
   {
   case 'A':
   case 'E':
   case 'I':
   case 'O':
   case 'U':
      bVowel = true;
      break;

   default:
      bVowel = false;
      break;
   }

【讨论】:

  • +1:非常简单实用的例子
  • case 'Y': bVowel = perhaps; break;
  • 哈哈! bVowel = (bool)0.125; // fuzzy logic bool 怎么样
  • 元音是不是元音的反义词?
【解决方案2】:

我认为这是一个错误功能,因为进入下一个区块的能力令人困惑且容易出错。想要匹配多个选项的常见情况会更好地编写:

switch (expression) {
   case 1, 7, 9:
      do something;
   case 2, 8, 10:
      do something else;
}

这不是 C++ 的选项,因为该语言被设计为相对向后兼容 C。

【讨论】:

  • 在这种情况下,这种语法会更好,但是您仍然可以通过 switch 来做一些事情,而您不能这样做。例如,假设案例 3 执行 C,案例 2 执行 B 和 C,案例 1 执行 A、B 和 C。这很优雅,但对于您建议的语法是不可能的(不重复 B 一次和 C 两次)。我想底线可能是灵活性——允许直通是提供切换的最灵活的方式(尽管直通应该是隐式还是显式是另一个问题)。
  • 同意你的看法,+1,但正如@Tyler 指出的那样,可能需要一个关键字才能在需要时通过。
【解决方案3】:

除了字数之外还有很多重要的因素:

  • switch 语句对表达式求值一次,而 if 语句的惰性编码可能会要求重复求值...如果代价高昂或有副作用,则不可取
  • 案例是否应该通过或需要中断因用法而异:如果相同的操作适用于许多案例,您可以节省大量字符
  • 优化器应该使 switch 语句在每次使用中至少与 if/else if/else 链一样有效,并且对于许多用途来说,它可以更有效(例如,在数组中查找值以切换到所需的行为/结果,构建二分搜索)
  • switch 语句更好地记录了决定流程的单个值,而 if/else-if/else 要求程序员分别检查每个表达式

【讨论】:

    【解决方案4】:

    你有一种非常奇怪的方式来决定哪个“更好”。一般来说,“更容易思考”是比“更短”更有用的测试。

    最终,这就是 C 语言的设计者所决定的,即提供可读性和易于编译的最佳组合的方式。

    使用任何体面的优化编译器,最终生成的程序可能不会有太大差异。

    【讨论】:

      【解决方案5】:

      编译器可以提出各种不同的策略来为 switch 语句生成机器码,即:

      • 查找表,当测试的值非常接近时
      • 二分查找,当有很多值时
      • 看起来就像 if-then 的代码。

      如今,编译器可能足够聪明,可以对一堆 if 语句进行此类优化,但在设计语言时肯定不是这种情况,switch 语句将所有信息在那里供编译器查看并决定生成什么代码。

      【讨论】:

        【解决方案6】:
        1. 每个“if”语句都必须在运行时进行评估。这可能取决于编译器优化。

        2. 据我所知,Switch 语句在评估每种情况的表达式方面效率更高。

        3. 如果您不添加 break,switch 语句将继续向下并可以执行更多情况。例如默认语句也是如此。例如如果/否则

        4. 我更喜欢 if/else if /else 因为如果你忘记了休息,它们就更难搞砸了。它们占用的空间更少,并且在其他编码器中更常见。但是你可以让 switch 语句看起来很漂亮。

        【讨论】:

        • 每个 switch 语句成员也在运行时进行评估。你觉得发生了什么,魔法?
        • 不是 1==1 编译器会默认为真。谢谢你这么有礼貌。
        • @billy,另请参阅下面的 Ken Blooms 声明,了解编译器如何构建哈希表以快速跳转到案例。
        • @John:当我发现它们明显错误时,我不会粉饰它们;对不起,如果我的直率听起来很粗鲁,但事实就是如此。我的观点是,是的,在某些情况下编译器可以加快开关中的查找速度。也就是说,情况并非总是如此——编译器不会做任何神奇的事情来使分支消失。此外,除非您有数百个分支生成像 IF/ELSE 一样运行的代码,否则无论如何都会更快。
        • 我喜欢这个问题现在由于“主观”和“争论”而被关闭
        【解决方案7】:

        这样Duff's Device 之类的东西就可以工作了。

        【讨论】:

        • 我认为这更像是一次意外。而且我认为您会感到一种黑暗的乐趣,将一个明显的新手指向一个非常糟糕的编程实践。 :-)
        • 嗯,是的,也不是。它确实表明了 C 和 C++ 中的 switch 和 case 语句如何与 goto 语句和标签密切相关。当您将switch() 视为一种计算的goto,将case 视为一种标签时,break 的原因就显而易见了。
        • 我原以为 switch 语句是为了在你有大量比较时比较懒惰
        【解决方案8】:

        C 被设计成易于编译。该语言的许多非常糟糕的方面,例如旧式参数传递,已被成功弃用。案例语句的设计使案例标签不必生成任何代码,但可以与“goto”标签类似地处理。现在没有特别需要易于编译的语言,但是如果不破坏 很多 代码,就不可能改变“switch”语句的工作方式。

        【讨论】:

          【解决方案9】:

          例如,对于 switch 语句,编译器可以制作一个 case 值和 goto 地址的映射并进行优化查找,而不是仅仅通过所有的“if”检查。

          【讨论】:

            猜你喜欢
            • 2018-09-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-22
            • 1970-01-01
            • 1970-01-01
            • 2013-07-31
            • 2013-08-20
            相关资源
            最近更新 更多