我没有使用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结构,但我不确定它是否是一种“可接受”的方式来使用它,或者是否有更好的方法。感谢。
答案 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
此模式有多种变体,具体取决于您需要清理的内容:
当你必须清理它时:
从函数返回的是什么:
您应该编写一个编码标准,明确指出每种不同变体的外观,因为其中一些变体可以用两种同样有效的方式设计。
注意:这仅适用于允许 // 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}}陈述。