如何从开关内部跳出循环?

新手上路,请多包涵

我正在编写一些看起来像这样的代码:

 while(true) {
    switch(msg->state) {
    case MSGTYPE: // ...
        break;
    // ... more stuff ...
    case DONE:
        break; // **HERE, I want to break out of the loop itself**
    }
}

有没有直接的方法可以做到这一点?

我知道我可以使用一个标志,并通过在切换后放置一个条件中断来中断循环。我只是想知道 C++ 是否已经有一些结构。

原文由 jrharshath 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 507
2 个回答

前提

无论语言或所需功能如何,都应将以下代码视为错误格式:

 while( true ) {
}

支持论点

while( true ) 循环的形式很差,因为它:

  • 打破 while 循环的隐含契约。
    • while 循环声明应明确声明 唯一 的退出条件。
  • 意味着它永远循环。
    • 必须阅读循环内的代码才能理解终止子句。
    • 永远重复的循环会阻止用户从程序中终止程序。
  • 是低效的。
    • 有多个循环终止条件,包括检查“真”。
  • 容易出现错误。
    • 无法轻松确定将始终为每次迭代执行的代码放置在何处。
  • 导致不必要的复杂代码。
  • 自动源代码分析。
    • 为了查找错误、程序复杂性分析、安全检查或在不执行代码的情况下自动导出任何其他源代码行为,指定初始中断条件允许算法确定有用的不变量,从而改进自动源代码分析指标。
  • 无限循环。
    • 如果每个人总是对非无限循环使用 while(true) ,那么当循环实际上没有终止条件时,我们就失去了简洁通信的能力。 (可以说,这已经发生了,所以这一点没有实际意义。)

“转到”的替代方案

以下代码是更好的形式:

 while( isValidState() ) {
  execute();
}

bool isValidState() {
  return msg->state != DONE;
}

优点

没有旗帜。没有 goto 。没有例外。容易改变。易于阅读。易于修复。另外代码:

  1. 将循环工作负载的知识与循环本身隔离开来。
  2. 允许维护代码的人轻松扩展功能。
  3. 允许在一处指定多个终止条件。
  4. 将终止子句与要执行的代码分开。
  5. 对核电站更安全。 ;-)

第二点很重要。在不知道代码如何工作的情况下,如果有人让我让主循环让其他线程(或进程)有一些 CPU 时间,我会想到两个解决方案:

选项1

轻松插入暂停:

 while( isValidState() ) {
  execute();
  sleep();
}

选项 #2

覆盖执行:

 void execute() {
  super->execute();
  sleep();
}

此代码比具有嵌入式 switch 的循环更简单(因此更易于阅读)。 isValidState 方法应该只确定循环是否应该继续。该方法的主力应抽象为 execute 方法,该方法允许子类覆盖默认行为(使用嵌入式 switchgoto 是一项艰巨的任务)64 .

Python 示例

对比 StackOverflow 上发布的以下答案(针对 Python 问题):

  1. 永远循环。
  2. 要求用户输入他们的选择。
  3. 如果用户的输入是’restart’,则永远继续循环。
  4. 否则,永远停止循环。
  5. 结尾。

代码

while True:
    choice = raw_input('What do you want? ')

    if choice == 'restart':
        continue
    else:
        break

print 'Break!'

相对:

  1. 初始化用户的选择。
  2. 循环,而用户的选择是“重启”这个词。
  3. 要求用户输入他们的选择。
  4. 结尾。

代码

choice = 'restart';

while choice == 'restart':
    choice = raw_input('What do you want? ')

print 'Break!'

在这里, while True 会导致误导和过于复杂的代码。

原文由 Dave Jarvis 发布,翻译遵循 CC BY-SA 4.0 许可协议

Because the switch uses the break to break out from the switch (not from the while(1) ), it needs the goto 声明:

 while(1) {
    switch (*p) {
      case ' ':
        p++;
        break;
      case '\n':
        p++; *s=p; return(i);
      case '\0':
        *s=p; return(i);
      default:
        token[i]=p;
        i++;
        p++;
        goto ex1;
    };
  };
  ex1:

我不能将多个案例添加到同一行,例如:

案例 “,’\t’:

这将是

案例”:案例’\t’:

这就是为什么这里使用的休息时间……

看起来最常见的情况应该放在列表的顶部,以使程序运行得更快。它可能没有并行执行来搜索不同的案例。

标准 c 可能缺少一些关于此切换的方法: https ://blog.hackajob.co/better-c-switch-statements-for-a-range-of-values/ => 允许您使用switch 表达式中的 <、>、<= 和 >= 运算符

我在想它应该是(如果 c 语言语法改变了)像:

 switch (c) {
  case >= 5:
     ... op1
  endcase;
  case == 1:
  case == 3:
     ... op2
  endcase;
  default:
    ...
};

其中,当 c 等于 1 或 3 时执行 op2,当 c 大于或等于 5 时执行 op1。因为以类似的方式很容易进行相等或大于/小于的比较。

   while(1) {
    switch (c) {
      case >= 2:
         ... op1
      case <= 5:
         ... op2
      break;
      default:
        ...
    };
  };

在这种情况下, op1 对大于 2 的 c 执行, op2 对 2<=c<=5 执行,并且 break 将其从 while 循环中退出。

原文由 user1070696 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏