Do-While循环的可接受使用?

时间:2011-04-22 02:13:48

标签: c# java c++ c do-while

  

可能重复:
  Coding Standards / Coding Best practices in C++

我没有使用Do-While循环很多但是我发现自己在一个特定类别的情况下使用它做了一些逻辑,我想要查看与多个退出点有关的事项列表但是只经过一次。我总是对条件有“while(TRUE)”和“if(TRUE)break”。在循环的最后,因为我只想通过它一次。 [我猜或者我可以将这些2组合为“while(FALSE)。”]

Do {

  // do some stuff

  if (!CheckCondition1) break;
  // do some stuff

  if (!CheckCondition2) break;
  // do some stuff

  ...

  // or delete this and change to while (FALSE);
  if (TRUE) break;
} while (TRUE);

我一直在这些情况下使用Do-While结构,但我不确定它是否是一种“可接受”的方式来使用它,或者是否有更好的方法。感谢。

7 个答案:

答案 0 :(得分:5)

我所知道的另一种方法是将代码放在一个函数中,并使用return代替break
但是,这有其自身的缺点:无法访问局部变量,创建甚至不存在的函数的额外复杂性,以及一些编码标准可能会强制您使用“单一退出点”。

所以,do {...} while(false);看起来好多了,只不过是蒙面goto。并且不要忘记,goto被禁止以避免spagetti代码,并且已经证明标准C控制流构造足以描述任何流。好吧,你刚刚完成了。

答案 1 :(得分:5)

在C(和C ++,如果你避免例外),最好使用goto。现在,不要用gotos替换结构化while循环的所有,但是如果你有这种模式来检查一堆不同的错误条件,并清除失败,{{ 1}}绝对是有道理的,而且它是表达你想要完成的事情的最明确方式之一。

(规范列表位于Examples of good gotos in C or C++

goto

此模式有多种变体,具体取决于您需要清理的内容:

  1. 无论你在函数中的位置有多远,清理都是一样的。
  2. 当你必须按照分配顺序的相反顺序清理东西时,数量会因你失败的地方而有所不同。
  3. 当你必须清理它时:

    1. 当您只需要在发生故障时进行清理。
    2. 如果你必须在成功的情况下清理相同的东西。
    3. 从函数返回的是什么:

      1. 即使发生故障,您也总是返回计算值。
      2. 如果成功,您将返回计算值,并在发生故障时返回特殊标记。
      3. 您应该编写一个编码标准,明确指出每种不同变体的外观,因为其中一些变体可以用两种同样有效的方式设计。

        注意:这仅适用于允许 // do some stuff if (!CheckCondition1) goto failure; // do some stuff if (!CheckCondition2) goto failure; // do some stuff return success_code; failure: //do something to clean up after a failure. //(I added that part, so it would be clear why you couldn't just return early) return failure_code; 的语言。这不包括Java,也许是C#。

答案 2 :(得分:2)

如果您打算这样做,最好使用while (true) {...}代替do {...} while (true)。这两者在功能上是等价的,但第一种形式更容易阅读。

与大多数人一样,我从上到下阅读代码。当我在循环的 start 处看到while (true)时,我立即知道循环终止逻辑必须在循环体内。但是,如果我看到do {..,我必须搜索相应的...} while (来解决这个问题。

(这与带有中断的while (true)是否优于while (flag)的问题是正交的,其中标志设置在循环中的各个点。)

答案 3 :(得分:0)

为什么你甚至想要做..在上面的情况下?做下面的事情,虽然取决于你在做什么。

 if (!CheckCondition1) return;
 // do some stuff

 if (!CheckCondition2) return;
 // do some stuff

答案 4 :(得分:0)

我发现do ... while的使用非常令人困惑和丑陋。至少在C中,for (;;)是无限循环的标准习语。完全看到do让我期待一些不合时宜的东西,while中的条件将变得很重要,只有找到TRUE(这也是不好的风格)那里......

答案 5 :(得分:0)

while {...} while(false);它通常用于处理c中的错误,例如:

int some_func(void)
{
    do {
        /* alloc some heap resources */

        /* do something */

        if (something goes wrong) break; /* error handling */

        /* do other things */

        return SUCCESS; 
    } while (false);

    /* release resources */

    return FAILURE;
}

在c ++中,您最好使用try { ... } catch(...)

答案 6 :(得分:-1)

我发现此do { } while();的使用非常可接受。前提是你应该放while(0)(现在你也可以使用continue)。因为如果你不break;,任何机会都会终止循环。 有趣的是,我在我以前公司的生产代码中看到了这种用法,这些代码由专家审核。

有人可能会想到使用return。但这种方法的问题是析构函数。请考虑以下情况:

void fun ()
{
  CLASS_a a1, a2, a3, a4;
  CLASS_b b1, b2, b3, b4;

  ...
  return 1;
  ...
  return 2;
  ...
  return 3;
  ...
  return 4;
}

在每个return语句中,将放置所有对象的析构函数代码。这可能会在不知不觉中增加代码大小。另外,我发现更好的退出点更少,这使得代码更易于调试。

修改:设置continue而不是break是一个更好的主意,因为当您在break内时,switch()将不允许退出循环{1}}陈述。