【问题标题】:Is It Possible To Do The Following In A Switch Statement - C++?是否可以在 switch 语句中执行以下操作 - C++?
【发布时间】:2010-01-19 15:52:25
【问题描述】:

我是第二节 OOP 课程的编程学生,我有一个简单的问题,我无法在互联网上找到答案,如果有,我深表歉意。

我的问题是这样的:

switch 语句中是否可以有布尔条件?

例子:

switch(userInputtedInt)
{
    case >= someNum && <= someOtherNum
    break;
    // Is this possible?
}

【问题讨论】:

  • 没有。而且我应该注意到,如果你使用开关,你几乎可以肯定没有在做 OOP。
  • @Neil:请解释一下。我们应该用完整的类层次结构替换程序中的所有布尔表达式吗?
  • 不。但是我们不应该假装我们在做 OOP——我们在做过程编程(不幸的是,没有很酷的 TLA)。
  • 为什么过程式编程不能成为 OOP 的一部分?我的意思是,我们不是 Smalltalk 纯粹主义者,是吗?或者,为什么 switch 语句不是 OOP,但 if 语句是?
  • @Brian 不是 ST 纯粹主义者,但我认为没有开关是 ST 做对的事情之一。恕我直言,任何 OOP 课程(以及 OP 确实问过这个问题)如果在第二堂课中专注于 switch/case 语法而不是(比如说)多态性,那么它将是有缺陷的。

标签: c++ switch-statement


【解决方案1】:

不,这在 C++ 中是不可能的。 Switch 语句仅支持整数和字符(它们将被它们的 ASCII 值替换)进行匹配。如果你需要一个复杂的布尔条件,那么你应该使用 if / else 块

【讨论】:

    【解决方案2】:

    正如其他人所说,您不能像您尝试那样直接实现此功能,因为 C++ 语法不允许这样做。但你可以这样做:

    switch( userInputtedInt )
    {
      // case 0-3 inclusve
      case 0 :
      case 1 :
      case 2 :
      case 3 :
        // do something for cases 0, 1, 2 & 3
        break;
    
      case 4 :
      case 5 :
        // do something for cases 4 & 5
        break;
    }
    

    【讨论】:

    • 这很有趣,它很好地利用了 C++ 对隐式掉线的支持。
    • @Alex:实际上,虽然 C++ 支持这一点,但我发现它通常不像你最初想象的那样具有表现力和实用性。像这样的 Switch 语句往往会变得很大,使它们难以阅读、维护和调试。在使用这样的开关之前,我通常会使用 ifs。或者更好的是,我会完全做其他事情。
    【解决方案3】:

    不,这通常是if 声明的权限:

    if ((userInputtedInt >= someNum) && (userInputtedInt <= someOtherNum)) { ... }
    

    当然,您可以将其合并到 switch 语句中:

    switch (x) {
        case 1:
            // handle 1
            break;
        default:
            if ((x >= 2) && (x <= 20)) { ... }
    }
    

    【讨论】:

      【解决方案4】:

      这是不可能的——C 或 C++ 的 switch 语句要求每个 case 都是常量,而不是布尔表达式。如果您有均匀分布的范围,您通常可以使用整数除法获得相同的效果。例如如果您有从 1 到 100 的输入,并且想将 90-100 作为一组,80-89 作为另一组,等等,您可以将输入除以 10,每个结果将代表一个范围。

      【讨论】:

        【解决方案5】:

        或者你可以这样做

        switch((userInputtedInt >= someNum) && (userInputtedInt <= someOtherNum))
        {
        case true:
             //do something
             break;
        case false: 
             //something else
             break;
        }
        

        但这只是可以用 if-else 语句处理的非常糟糕的编程。

        【讨论】:

          【解决方案6】:

          这是不可能的。如果这些值相当接近,则最接近的是

          switch(userInputtedInt)
          {
              case someNum:
              case someNum+1:
              // ... 
              case someOtherNum:
              break;
          
          }
          

          【讨论】:

            【解决方案7】:

            C++ 不支持。

            但是,如果您不关心编写可移植的标准代码,一些编译器支持这种扩展语法:

            switch(userInputtedInt)
            {
                case someNum...someOtherNum:
                break;
            }
            

            这些值必须是常数。

            【讨论】:

            • 哪些编译器支持该语法?
            • 我想我记得 Metrowerks 支持它。也许其他人?当然,它只是键入几个相邻案例标签的简写。
            【解决方案8】:

            如果您喜欢预处理器,您可以编写某种宏来自动扩展所需的 case 语句的数量。但是,这将需要一个包含几乎所有案例语句的冗长文件(例如:#define CASE0 案例 0:#define CASE1 案例 1:...)

            你不应该去那里,但这样做很有趣……为了好玩! ;)

            【讨论】:

              【解决方案9】:

              标准不允许这样做:

              6.4.2 switch 语句 [stmt.switch]

              [...] switch 语句中的任何语句都可以用一个或多个 case 标签进行标记,如下所示:

              case constant-expression :

              其中常量表达式应为整数常量表达式 (5.19)。

              【讨论】:

                【解决方案10】:

                在最初提出这个问题 8 年后,今天一些 C++ 编译器仍然支持范围表示法。这让我很惊讶。

                我在 2012 年学习了 Pascal,Pascal 确实有范围符号。 所以它鼓励我在 C++ 中尝试类似的语法,然后它出乎意料地工作了。

                我笔记本电脑上的编译器是 g++ (GCC) 6.4.0(来自 Cygwin 项目)std=c++17

                有一个工作示例,我匆忙写了。 repl.it

                另外附上源码:

                #include <iostream>
                using namespace std;
                #define ok(x) cout << "It works in range(" << x << ")" << endl
                #define awry cout << "It does\'t work." << endl
                
                int main() {
                    /*bool a, b, c, d, e, f, g;
                    switch(true) {
                        case (a): break;            These does not work any more...
                        case (b and c): break;
                    }*/
                    char ch1 = 'b';
                    switch(ch1) {
                        case 'a' ... 'f': ok("a..f"); break;
                        case 'g' ... 'z': ok("g..z"); break;
                        default: awry;
                    }
                    int int1 = 10;
                    switch(int1) {
                        case 1 ... 10: ok("1..10"); break;
                        case 11 ... 20: ok("11..20"); break;
                        default: awry;
                    }
                
                    return 0;
                }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-10-13
                  • 2021-08-11
                  • 2014-09-10
                  • 1970-01-01
                  • 2015-06-09
                  • 2021-11-04
                  • 2022-01-24
                  相关资源
                  最近更新 更多