在C和javascript中,我喜欢写这种东西的能力,并让它工作。
while (a)
{
ctx: while(b)
{
while (c)
{
if(d) break ctx;
...
}
}
...
}
也许我只是对C ++版本感到困惑,但我在g ++中遇到了这种错误:
error: expected ‘;’ before ‘ctx’
break ctx;
error: ‘ctx’ was not declared in this scope
warning: label ‘ctx’ defined but not used [-Wunused-label]
ctx:
C ++似乎拒绝让我编写这段代码。 C ++已经添加了lambdas / closures,可能会让我这样做,但我不太确定它们在这种情况下会如何工作。
使用try throw catch是我能想到的最接近的构造产生这种行为,但是当不需要任何东西时使用错误系统的麻烦关注我(我听到它们也很慢)。
我很想将它包装在extern C中,除非我完全依赖于c ++库来完成整个项目,所以这也感觉很邋..
尝试阻止或只是重写我唯一的选择?
C和C ++都没有标记的break语句(你可能使用的是语言扩展,而不是标准的C语言)。
相反,您可以使用goto
来打破嵌套循环。
while (a)
{
while(b)
{
while (c)
{
if(d)
goto break_b;
}
}
break_b:
// ...
}
我能够使用goto来解决这个问题...我认为它是c ++中的禁止构造?
没有.goto
在C ++中没有被“禁止”。
这是一个使用goto
的完美方式。不存在等效的结构化控制语句。
lambdas / closures [...]可能会让我这样做,但我不太确定它们在这种情况下会如何工作。
如果你对goto
过敏,那么你确实可以使用lambda,但我不认为它提供任何额外的可读性:
while (a)
{
[&](){
while(b)
{
while (c)
{
if(d)
return;
}
}
}();
// ...
}
您可以使用命名函数代替lambda。但在这种情况下,你需要传递任何变量(如b
,c
和d
)作为参数(假设它们不是全局变量)。
另一种方式是额外的变量:
while (a)
{
bool break_b = false;
while(b)
{
while (c)
{
if(d) {
break_b = true;
break;
}
}
if (break_b)
break;
}
// ...
}
在这三种方法中,我推荐goto
,因为它是最具可读性的。除了在示例中省略的实际内循环非常长的情况,在这种情况下,单独的函数可能更好。
正如其他人已经指出的那样,goto
将是一种完全符合您要求的方式。
话虽这么说,我认为,在提出如何摆脱大规模复杂的控制流结构的问题之前,你应该首先问问自己为什么有一个大规模复杂的流程结构开始。这些循环中发生了什么?如果每个循环中发生的事情都不能更好地转移到它自己的功能中吗?例如,而不是
while (a)
{
ctx: while (b)
{
while (c)
{
if (d) goto ctx;
…
}
}
…
}
为什么不
bool doC()
{
while (c)
{
if (d)
return false;
…
}
return true;
}
void doB()
{
while (b && doC());
}
然后
while (a)
{
doB();
…
}
在这里用goto替换断点是不可取的。可能存在未正确调用构造函数和析构函数的问题。虽然goto仍然存在于C ++中,但除非你真的知道自己在做什么,否则它真的不是你想要使用的东西!更安全的选择是使用try-catch块。一个更好的方法是重新计算你的算法(目前它是O(N ^ 3),这应该真的响起一些警钟!)
while (a)
{
try
{
while(b)
{
while (c)
{
if(d) throw;
}
}
}
catch(...)
{
}
}