3

我最近遇到了这段代码:

do {
    if ( ! checkSomething() )
        break;

    // some code

    if ( ! checkSomeOtherThing() )
        break;

    // some other code
} while(false);

// some final code

编写它的程序员,沿着"cleaner control flow".

在我看来,如果将原始代码重构为其他内容,它可能看起来会更好。但这种说法有任何道理吗?这个结构好用吗?

4

4 回答 4

6

我发现这更容易阅读,并且产生相同的结果:

if ( checkSomething() )
{
    // some code
    if ( checkSomeOtherThing() )
    {
        // some other code
    }
}
// some final code

我认为do ... while通常很难理解,但是将它用于循环以外的其他东西充其量是误导。

于 2010-12-06T00:10:28.960 回答
3

这相当于一个goto.

在这种情况下,使用 agoto比使用丑陋的 hack 更好。

将其更改为使用 agoto使其更具可读性:

if (!checkSomething())
    goto Done;

// some code

if (!checkSomeOtherThing())
    goto Done;

// some other code
Done: //some final code
于 2010-12-06T00:20:10.663 回答
2

如果您不介意包含多个break语句的循环,那么这里唯一的问题是 C(出于显而易见的原因)不允许您跳出裸块,因此一些毫无戒心的未来维护者可能会误认为“非循环”对于一个真正的循环。

我认为考虑的因素是:

  • 如果只有break两点,那么两个if陈述有什么不好?
  • 如果有两个以上的断点,那么带有if语句的缩进可能会令人不快,这可以节省这一点,但是该函数又做得太多了?即使不是,使用goto并避免不循环的循环的怪异会更好吗?

由于您标记了这种与语言无关的标签,因此我曾经使用宏化的汇编语言,带有block...endblock您可以摆脱它。这导致了用于检查必要条件的相当不错的代码,例如:

block
    breakif str1 == null
    breakif str2 == null
    get some combined property of str1 and str2
    breakif some other condition that stops us getting on with it
    get on with it
endblock

实际上,它不是breakif str1 == null,它是breakifeq.p str1, null,或类似的东西,但我忘记了具体是什么。

于 2010-12-06T00:16:32.847 回答
0

我已经看到采用 do-while 形式作为编码人员遵循的标准。优点是它传达并实现了循环将始终至少执行一次。这有助于以一致的方式隔离发生不同情况的情况,即循环中的代码未执行的情况。

采用该标准是因为应用了 Warnier-Orr 技术。

于 2010-12-06T04:06:11.840 回答