哪个更好?do{} while(0); 还是 goto xy;?

4

I've two pieces of code:

A do while loop:

do
{
    errorflag=0;
    ...
    if(cond1)
    {
        errorFlag=12;
        break;   // Error Conditions
    }
    .
    .            // Processing
    .
    if(cond2)  
    {
        errorflag=56;
        break;
    }
     .
     .

} while (0);

一个goto标签:
errorflag=0;
if(cond1)
{
     errorflag=12;
     goto xy;
 .
 .
 .
 .
if(Cond2)
{
     errorflag=56;
     goto xy;
}
.
.
.

xy:

哪个更好?请给我详细原因,还是有更好的方法来做这个?我们正在优化代码。我们最关注这些大循环。在汇编级别上,没有太多的优化空间。请提供您的意见。

我不喜欢使用else-if,因为它再次检查了一个条件,这是一种负担。所以当出现问题时直接退出。

我感觉经过这次编辑我的问题已经有意义了。

提前感谢您。


2
一个简单的 else if 有什么问题吗?有多少个条件?这实际上是哪种语言? - Dirk Vollmar
4
这不是一个很好的问题。这就像是“用钝勺子挖出我的脑袋还是用坚果夹压碎我的睾丸,哪个更好?”两者都一点也不好,要避免它们!此外,“do...while”通常(但并非总是)是你编写代码有误的标志。除非确实真的有意义,否则要避免使用它。我知道很多人会不同意这个说法,但我一直发现“while...do”结构更容易阅读,而且通常更好。 - AlastairG
1
@AlastairG:被压碎睾丸是可以生存的。显然这是更好的选择。话虽如此,我认为我会避免滥用C控制结构,以免受到任何惩罚。我同意你关于do ... while()的看法,只是我不使用它。 - JeremyP
@AlastairG:关于我的问题。我有一个代码块,在其中有一系列的退出条件,这些条件取决于它所处理的内容,就在条件语句的上方。因此,使用while...do是无用的,因为它首先检查条件,所以会增加额外的开销。在我们的情况下,这是一个经常使用的函数。这就是为什么我们使用do...while的原因。在我们的情况下,这是有意义的。 - Rajeev
一个类似的问题及其答案:https://dev59.com/oHM_5IYBdhLWcg3wWRyV - anatolyg
5个回答

13

选项3:

void frobnicate(arguments) 
{
  if (cond1) return;
  if (cond2) return; 

  ...
}

frobnicate(the_arguments)

选择一个有意义且简短的名称。


2
如果没有回答问题,请将虚拟值设为-1。你的“...”应该在两个if之间。 - JeremyP
1
在许多情况下这并不起作用(例如当您需要在返回之前进行清理时)。 - PoVa

5
他们生成相同的代码(假设编译器值得考虑),所以区别在于哪个更容易理解,以及do/while是否会干扰其他循环结构。如果存在这样的干扰,请使用goto。否则不要使用;它们不太清晰(通常情况下)。
并仔细查看您的函数是否过于复杂,应将其重构为具有更清晰目的和更简单控制流的多个函数。

3
严肃点,你从来没听说过 else 吗?
if (cond1)
{
    //stuff
}
else if (cond2)
{
    // more stuff
}
// etc

else
{
    // default
}

编辑

我误读了问题。但是我会保留旧回答,因为否则评论就没有意义了。

按照问题中的要求编写代码的正确方式是:

if (!cond1)
{
    .
    .
    .
    .
}

在这两种情况中,假设cond2没有副作用,if (cond2)部分都没有影响,因为它们都会跳转到下一个将要执行的语句。这就是我省略它的原因。

为什么要踩?根据所使用的编程语言和条件数量,此代码很直观且易于阅读。当然,长而复杂的嵌套if语句总是重构的好候选对象,但在这种情况下,我们对假设任何类似的事情都知之甚少。 - Dirk Vollmar
@0xA3:这不是问题的解决方案,所以。 - Donal Fellows
从初始代码来看,基于if的解决方案应该是if (!cond1) { ... if(!cond2) { ... } }(不需要else)。 - Victor Nicollet
@Victor Nicollet:我明白你的意思了,我误读了原文。我正在编辑我的答案。 - JeremyP
@Donald Fellows,@Victor Nicollet,@JeremyP:这里的问题在于问题只显示了一个代码片段,这是相当无用的。鉴于条件本身没有副作用,您可以简单地删除所有代码。但是OP已经离开现场,所以我们不知道代码实际上应该做什么。 - Dirk Vollmar
@0xA3:如果cond1被评估为true,您不执行任何内容,但如果它被评估为false,您将通过点状位。 - JeremyP

-4

goto是邪恶的。你应该只在绝对没有其他方法时使用gotogoto可能会导致不可预测的意大利面条式代码(难以阅读、理解、调试,非常容易在维护阶段出错)。

我认为一个带有条件break语句的无限循环仍然更好,尽管当条件在while语句中表达时更易读。


1
这里的循环不是无限的。似乎一个简单的“else if”就可以解决问题…(这也展示了代码有多容易被误读,正如@Victor Nicollet的评论中已经提到的那样) - Dirk Vollmar
3
在这种情况下使用goto比滥用do/break/while结构更清晰。 - salva
2
@salva:使用if语句会更好。 - JeremyP
goto是邪恶的”这种说法是由狂热者传播出去的教条。仅仅因为一个名字就对某个东西嗤之以鼻是不好的。其他控制语句也可能导致代码难以阅读。仅仅因为goto可以被用于不良方式,它并不完全是坏的。 - glglgl
不,主要是因为代码会变得难以阅读。一个好的goto语句会引导你到另一个地方,过一段时间后,每个查看你代码的开发人员都会诅咒你。初级开发人员(甚至高级开发人员)使用while和for循环就足以让代码变得糟糕。一旦他们获得了使用goto语句的许可 - 你就完了。如果你使用像C这样的语言,绝对没有理由使用goto语句。只要你不能证明我错了,你对两个答案的投票只会让我认为你是一个孤独、愤怒的老派开发人员,而绝不是一个好的开发人员。 - Alex
显示剩余2条评论

-9

根据你的问题,这里的选择是do-whilegoto

我建议你选择do-while

我不鼓励你使用goto。那会导致你以后编写出意大利面条式代码。

你可以使用ifif-else等替代方案来达到相同的结果。

goto说不。


6
这是一个无意义的陈述。你可以在不使用“goto”的情况下完美地编写“意大利面代码”,并且你可以编写包含“goto”(例如用于错误处理)的清晰代码。 - glglgl
@glglgl 同样适应错误处理的编程语言。例如,使用结构化异常处理和finally子句。如果问题足够好,编程语言会适应得更好(只要不会破坏语言本身)。使用goto仍然意味着您需要记住在处理错误时跳转到特定的标签 - 使用finally/catch让您像其他任何地方一样使用return。这在复制代码时尤其重要-很容易忘记将一个return更改为goto releaseStuff; - Luaan
@Luaan 如果你使用的是有适当异常处理机制的语言,那么确实没有使用goto的理由。但在C语言中,这通常是最简单的方法。 - glglgl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接