这是使用goto的可接受方式吗?

ils*_*tam 1 c goto

假设我想写一个游戏(用C语言),询问用户在游戏结束后是否想再次玩游戏.

我看到两种明显的方式来写这个.

第一:

int main(void)
{
    /* variable declarations and initializations */

    do { /* optionally multiple games */

        /* game code here */
        ........

        /* prompt user wheter he wants to play again */
        bool playagain = playagain();

    } while(playagain);

    .....
}
Run Code Online (Sandbox Code Playgroud)

第二个:

int main(void)
{
    /* variable declarations and initializations */

game_start: /* optionally multiple games */

    /* game code here */
    ........

    /* prompt user wheter he wants to play again */
    bool playagain = playagain();

    if (playagain)
        goto game_start;

    .....
}
Run Code Online (Sandbox Code Playgroud)

我知道通常使用goto语句是一个坏主意,但我认为这使代码更清晰,并使我们免于额外的缩进级别.

所以我的问题是,这个特定的例子是否被认为是使用goto语句的正确方法,或者我应该避免它?

Dav*_*eri 6

这不是更好的例子,在K&R中你可以找到一个好的例子:

C提供无限可滥用的goto语句,以及要转移到的标签.形式上,goto语句从来都不是必需的,在实践中,没有它就可以很容易地编写代码.我们在本书中没有使用过goto.然而,有一些情况下,gotos可能会找到一个地方.最常见的是放弃一些深层嵌套结构中的处理,例如一次性断开两个或多个循环.break语句不能直接使用,因为它只从最里面的循环退出.从而:

         for ( ... )
              for ( ... ) {
                  ...
                  if (disaster)
                       goto error;
              }
         ...
   error:
         /* clean up the mess */
Run Code Online (Sandbox Code Playgroud)

如果错误处理代码非常重要,并且在多个位置可能发生错误,则此组织非常方便.

  • 这是一个合法的例子,但IMO更好的解决方案是在单独的函数中编写嵌套循环并使用return语句,或使用try-catch块(不特定于C) (2认同)
  • @MarkusUnterwaditzer 因为 C 没有例外,所以“goto”的这种特殊用法可能是解决某些问题的最佳方法。当然,使用异常会更好,但如果语言不支持它们,那不是一个很有建设性的评论。 (2认同)