1

可能重复:
C++ 中的编码标准/编码最佳实践

我不经常使用 Do-While 循环,但我发现自己在一个特定类别的情况下使用它做一些逻辑,我想通过一个与多个退出点有关的事情列表,但只通过一次。对于条件,我总是有“while (TRUE)”和“if (TRUE) break;”。在循环的最后,因为我只想通过它一次。[我想或者我可以将这两个组合为“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 构造,但我不确定它是否是一种“可接受的”使用方式,或者是否有更好的方式。谢谢。

4

7 回答 7

5

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

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

于 2011-04-22T02:25:58.703 回答
5

在 C (和 C++,如果你要避免异常)中,最好使用 a goto。现在,不要用 goto 替换所有结构化while循环,但是当您有这种检查一堆不同错误条件并从故障中清除的模式时,这goto是绝对有必要的,这是最清晰的表达方式之一你想要完成的事情。

(规范列表位于 C 或 C++ 中的良好 goto 示例中

  // 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;

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

  1. 无论你在函数中的位置有多远,清理都是相同的。
  2. 当您必须以与分配相反的顺序清理东西时,数量会因您失败的位置而异。

当你必须清理它时:

  1. 当您只需要在发生故障时进行清理时。
  2. 当您必须在成功的情况下清理相同的东西时。

以及从函数返回的内容:

  1. 即使发生故障,您也总是返回一个计算值。
  2. 您在成功的情况下返回一个计算值,并在失败的情况下返回一个特殊的哨兵。

您应该编写一个编码标准,明确指定这些不同变体中的每一个的外观,因为其中一些变体可以以两种同样有效的方式设计。

注意:这仅适用于允许goto. 这不包括 Java,也许还有 C#。

于 2011-04-22T02:43:07.920 回答
2

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

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

while (true)(这与中断是否比while (flag)在循环中的各个点设置标志的位置更好的问题正交。)

于 2011-04-22T04:47:44.377 回答
0

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

于 2011-04-22T02:24:19.843 回答
0

做 { ... } 而(假);它通常用于处理 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(...)

于 2011-04-22T02:38:08.557 回答
0

在上述情况下,您为什么还要 do..while 呢?做类似下面的事情,虽然取决于你在做什么。

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

 if (!CheckCondition2) return;
 // do some stuff
于 2011-04-22T02:17:16.320 回答
-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()

于 2011-04-22T02:28:51.697 回答