【问题标题】:Mingling switch and while in C [duplicate]混合开关和 C [重复]
【发布时间】:2013-03-06 18:52:24
【问题描述】:

这段代码出于某种原因可以工作,但根本没有意义。

#include <stdio.h>

int main(void)
{
  switch(1)
    {
      case 0:
        while(1)
          {
            case 1: puts("Works"); break;
          }
    }
  return 0;
}

有人能解释一下它为什么会起作用以及它有哪些应用程序吗?

【问题讨论】:

  • @0A0D 这是一个不同的问题!
  • @saadtaame:对我来说看起来一样。这是 Duff 的设备。

标签: c while-loop switch-statement


【解决方案1】:

case 标签几乎与goto 使用的标签完全相同。1 如果您以这些术语来考虑您的代码,那么应该清楚它是有效的。也就是说,您可以将switch 语句视为美化条件goto

也就是说,我会扇任何在生产环境中编写类似代码的人。2


  1. 事实上,它们都列在 C99 标准的同一语法部分 (6.8.1) 中。

  2. 是的,这与Duff's device 几乎相同,但最后一个在几十年前有任何实际用途。

【讨论】:

  • 尽可能提供标准链接? (或确切的部分:D)
  • @saadtaame:请参阅我回答中的脚注!
  • 我看到它在模仿 C 中异常的代码中使用。
【解决方案2】:

这个工作的原因有点不直观:switch 语句的case 标签与常规标签非常相似,即设计用于goto 语句的标签。您可以在代码中的任何位置放置此类标签。

事实证明,同样的规则也适用于case 标签:您可以将它们放在相应的switch 语句中的任何位置,其中顺便包括任何嵌套循环的主体。

您可能想要switch 语句主体内的控制语句中放置标签的原因甚至更不直观:事实证明,您可以执行循环展开,但看起来很麻烦但非常直观的构造称为Duff's Device。正是这种构造导致了在switch 语句中的其他控制结构中嵌入案例标签的想法。

【讨论】:

  • 谢谢。什么是循环展开?我有兴趣
  • @saadtaame 循环展开(又名“循环展开”)是指重复循环主体数次(例如四次),同时减少循环执行的次数。这以更少的迭代完成相同数量的工作,从而降低了每次迭代的成本(检查退出条件和递增索引)。这是a link to a wiki article./wiki/Loop_unwinding
【解决方案3】:

您可以通过switch 的标签交错语句,因为它们只是标签。这里发生的是:

  • 您使用while (1) 定义了一个无限循环;
  • switch (1) 语句跳转到case 1: 标签;
  • 在哪里打印"Works",然后break; 退出无限循环。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-18
    • 2013-02-13
    • 1970-01-01
    • 1970-01-01
    • 2011-09-15
    • 1970-01-01
    相关资源
    最近更新 更多